module SPARC.CodeGen.Base (



import SPARC.Instr
import SPARC.Cond
import SPARC.AddrMode
import SPARC.Regs
import SPARC.RegPlate
import Size
import Reg

import Cmm

import Outputable
import OrdList

-- | 'InstrBlock's are the insn sequences generated by the insn selectors.
-- 	They are really trees of insns to facilitate fast appending, where a
-- 	left-to-right traversal yields the insns in the correct	order.
type InstrBlock 
	= OrdList Instr

-- | Condition codes passed up the tree.
data CondCode 	
	= CondCode Bool Cond InstrBlock

-- | a.k.a "Register64"
--	Reg is the lower 32-bit temporary which contains the result. 
--	Use getHiVRegFromLo to find the other VRegUnique.  
--	Rules of this simplified insn selection game are therefore that
--	the returned Reg may be modified
data ChildCode64 	
   = ChildCode64 

-- | Holds code that references a memory address.
data Amode 
	= Amode 
		-- the AddrMode we can use in the instruction 
		--	that does the real load\/store.

		-- other setup code we have to run first before we can use the
		--	above AddrMode.

-- | Code to produce a result into a register.
--	If the result must go in a specific register, it comes out as Fixed.
--	Otherwise, the parent can decide which register to put it in.
data Register
	= Fixed	Size Reg InstrBlock
	| Any	Size (Reg -> InstrBlock)

-- | Change the size field in a Register.
	:: Register -> Size -> Register

setSizeOfRegister reg size
 = case reg of
 	Fixed _ reg code 	-> Fixed size reg code
	Any _ codefn     	-> Any   size codefn

-- | Grab the Reg for a CmmReg
getRegisterReg :: CmmReg -> Reg

getRegisterReg (CmmLocal (LocalReg u pk))
  	= RegVirtual $ mkVirtualReg u (cmmTypeSize pk)

getRegisterReg (CmmGlobal mid)
  = case globalRegMaybe mid of
        Just reg -> RegReal reg
        Nothing  -> pprPanic
                        "SPARC.CodeGen.Base.getRegisterReg: global is in memory"
                        (ppr $ CmmGlobal mid)

-- Expand CmmRegOff.  ToDo: should we do it this way around, or convert
-- CmmExprs into CmmRegOff?
mangleIndexTree :: CmmExpr -> CmmExpr

mangleIndexTree (CmmRegOff reg off)
	= CmmMachOp (MO_Add width) [CmmReg reg, CmmLit (CmmInt (fromIntegral off) width)]
	where width = typeWidth (cmmRegType reg)

mangleIndexTree _
	= panic "SPARC.CodeGen.Base.mangleIndexTree: no match"