import MachRegs
import OrdList ( OrdList, nilOL, isNilOL, unitOL, appOL, toOL,
snocOL, consOL, concatOL )
-import AbsCSyn ( MagicId )
import AbsCUtils ( magicIdPrimRep )
import CallConv ( CallConv )
-import CLabel ( isAsmTemp, CLabel, pprCLabel_asm )
+import CLabel ( isAsmTemp, CLabel, pprCLabel_asm, labelDynamic )
import Maybes ( maybeToBool, expectJust )
import PrimRep ( isFloatingRep, PrimRep(..) )
import PrimOp ( PrimOp(..) )
import CallConv ( cCallConv )
import Stix ( getNatLabelNCG, StixTree(..),
- StixReg(..), CodeSegment(..),
- pprStixTrees, ppStixReg,
+ StixReg(..), CodeSegment(..), DestInfo,
+ pprStixTree, ppStixReg,
NatM, thenNat, returnNat, mapNat,
mapAndUnzipNat, mapAccumLNat,
getDeltaNat, setDeltaNat
)
import Outputable
+import CmdLineOpts ( opt_Static )
infixr 3 `bind`
LABEL lab)))
StFunEnd lab -> IF_ARCH_alpha(returnNat (unitOL (FUNEND lab)),
returnNat nilOL)
+
StLabel lab -> returnNat (unitOL (LABEL lab))
- StJump arg -> genJump arg
- StCondJump lab arg -> genCondJump lab arg
- StCall fn cconv VoidRep args -> genCCall fn cconv VoidRep args
+ StJump dsts arg -> genJump dsts (derefDLL arg)
+ StCondJump lab arg -> genCondJump lab (derefDLL arg)
+
+ -- A call returning void, ie one done for its side-effects
+ StCall fn cconv VoidRep args -> genCCall fn
+ cconv VoidRep (map derefDLL args)
StAssign pk dst src
- | isFloatingRep pk -> assignFltCode pk dst src
- | otherwise -> assignIntCode pk dst src
+ | isFloatingRep pk -> assignFltCode pk (derefDLL dst) (derefDLL src)
+ | otherwise -> assignIntCode pk (derefDLL dst) (derefDLL src)
StFallThrough lbl
-- When falling through on the Alpha, we still have to load pv
where
getData :: StixTree -> NatM (InstrBlock, Imm)
- getData (StInt i) = returnNat (nilOL, ImmInteger i)
- getData (StDouble d) = returnNat (nilOL, ImmDouble d)
- getData (StLitLbl s) = returnNat (nilOL, ImmLab s)
- getData (StCLbl l) = returnNat (nilOL, ImmCLbl l)
- getData (StString s) =
+ getData (StInt i) = returnNat (nilOL, ImmInteger i)
+ getData (StDouble d) = returnNat (nilOL, ImmDouble d)
+ getData (StFloat d) = returnNat (nilOL, ImmFloat d)
+ getData (StCLbl l) = returnNat (nilOL, ImmCLbl l)
+ getData (StString s) =
getNatLabelNCG `thenNat` \ lbl ->
returnNat (toOL [LABEL lbl,
ASCII True (_UNPK_ s)],
getData (StIndex rep (StCLbl lbl) (StInt off)) =
returnNat (nilOL,
ImmIndex lbl (fromInteger (off * sizeOf rep)))
+
+-- Walk a Stix tree, and insert dereferences to CLabels which are marked
+-- as labelDynamic. stmt2Instrs calls derefDLL selectively, because
+-- not all such CLabel occurrences need this dereferencing -- SRTs don't
+-- for one.
+derefDLL :: StixTree -> StixTree
+derefDLL tree
+ | opt_Static -- short out the entire deal if not doing DLLs
+ = tree
+ | otherwise
+ = qq tree
+ where
+ qq t
+ = case t of
+ StCLbl lbl -> if labelDynamic lbl
+ then StInd PtrRep (StCLbl lbl)
+ else t
+ -- all the rest are boring
+ StIndex pk base offset -> StIndex pk (qq base) (qq offset)
+ StPrim pk args -> StPrim pk (map qq args)
+ StInd pk addr -> StInd pk (qq addr)
+ StCall who cc pk args -> StCall who cc pk (map qq args)
+ StInt _ -> t
+ StFloat _ -> t
+ StDouble _ -> t
+ StString _ -> t
+ StReg _ -> t
+ StScratchWord _ -> t
+ _ -> pprPanic "derefDLL: unhandled case"
+ (pprStixTree t)
\end{code}
%************************************************************************
]
where
shift DoubleRep = 3::Integer
- shift CharRep = 0::Integer
+ shift CharRep = 2::Integer
+ shift Int8Rep = 0::Integer
shift _ = IF_ARCH_alpha(3,2)
\end{code}
\begin{code}
maybeImm :: StixTree -> Maybe Imm
-maybeImm (StLitLbl s) = Just (ImmLab s)
-maybeImm (StCLbl l) = Just (ImmCLbl l)
-
-maybeImm (StIndex rep (StCLbl l) (StInt off)) =
- Just (ImmIndex l (fromInteger (off * sizeOf rep)))
-
+maybeImm (StCLbl l)
+ = Just (ImmCLbl l)
+maybeImm (StIndex rep (StCLbl l) (StInt off))
+ = Just (ImmIndex l (fromInteger (off * sizeOf rep)))
maybeImm (StInt i)
| i >= toInteger minInt && i <= toInteger maxInt
= Just (ImmInt (fromInteger i))
-- cannae be Nothing
getRegister (StReg (StixTemp u pk))
- = returnNat (Fixed pk (UnmappedReg u pk) nilOL)
+ = returnNat (Fixed pk (mkVReg u pk) nilOL)
getRegister tree@(StIndex _ _ _) = getRegister (mangleIndexTree tree)
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if i386_TARGET_ARCH
+getRegister (StFloat f)
+ = getNatLabelNCG `thenNat` \ lbl ->
+ let code dst = toOL [
+ SEGMENT DataSegment,
+ LABEL lbl,
+ DATA F [ImmFloat f],
+ SEGMENT TextSegment,
+ GLD F (ImmAddr (ImmCLbl lbl) 0) dst
+ ]
+ in
+ returnNat (Any FloatRep code)
+
+
getRegister (StDouble d)
| d == 0.0
= let code dst = unitOL (GLDZ dst)
- in trace "nativeGen: GLDZ"
- (returnNat (Any DoubleRep code))
+ in returnNat (Any DoubleRep code)
| d == 1.0
= let code dst = unitOL (GLD1 dst)
- in trace "nativeGen: GLD1"
- returnNat (Any DoubleRep code)
+ in returnNat (Any DoubleRep code)
| otherwise
= getNatLabelNCG `thenNat` \ lbl ->
Int2DoubleOp -> coerceInt2FP DoubleRep x
other_op ->
- let
- fixed_x = if is_float_op -- promote to double
- then StPrim Float2DoubleOp [x]
- else x
- in
getRegister (StCall fn cCallConv DoubleRep [x])
where
(is_float_op, fn)
other
-> pprPanic "getRegister(x86,unary primop)"
- (pprStixTrees [StPrim primop [x]])
+ (pprStixTree (StPrim primop [x]))
getRegister (StPrim primop [x, y]) -- dyadic PrimOps
= case primop of
[x, y])
other
-> pprPanic "getRegister(x86,dyadic primop)"
- (pprStixTrees [StPrim primop [x, y]])
+ (pprStixTree (StPrim primop [x, y]))
where
--------------------
in
returnNat (Any PtrRep code)
| otherwise
- = pprPanic "getRegister(x86)" (pprStixTrees [leaf])
+ = pprPanic "getRegister(x86)" (pprStixTree leaf)
where
imm = maybeImm leaf
imm__2 = case imm of Just x -> x
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if sparc_TARGET_ARCH
+getRegister (StFloat d)
+ = getNatLabelNCG `thenNat` \ lbl ->
+ getNewRegNCG PtrRep `thenNat` \ tmp ->
+ let code dst = toOL [
+ SEGMENT DataSegment,
+ LABEL lbl,
+ DATA F [ImmFloat d],
+ SEGMENT TextSegment,
+ SETHI (HI (ImmCLbl lbl)) tmp,
+ LD F (AddrRegImm tmp (LO (ImmCLbl lbl))) dst]
+ in
+ returnNat (Any FloatRep code)
+
getRegister (StDouble d)
= getNatLabelNCG `thenNat` \ lbl ->
getNewRegNCG PtrRep `thenNat` \ tmp ->
in
returnNat (Any DoubleRep code)
+-- The 6-word scratch area is immediately below the frame pointer.
+-- Below that is the spill area.
+getRegister (StScratchWord i)
+ | i >= 0 && i < 6
+ = let j = i+1
+ code dst = unitOL (fpRelEA j dst)
+ in
+ returnNat (Any PtrRep code)
+
+
getRegister (StPrim primop [x]) -- unary PrimOps
= case primop of
- IntNegOp -> trivialUCode (SUB False False g0) x
- NotOp -> trivialUCode (XNOR False g0) x
+ IntNegOp -> trivialUCode (SUB False False g0) x
+ NotOp -> trivialUCode (XNOR False g0) x
- FloatNegOp -> trivialUFCode FloatRep (FNEG F) x
+ FloatNegOp -> trivialUFCode FloatRep (FNEG F) x
+ DoubleNegOp -> trivialUFCode DoubleRep (FNEG DF) x
DoubleNegOp -> trivialUFCode DoubleRep (FNEG DF) x
Double2FloatOp -> trivialUFCode FloatRep (FxTOy DF F) x
Float2DoubleOp -> trivialUFCode DoubleRep (FxTOy F DF) x
- OrdOp -> coerceIntCode IntRep x
- ChrOp -> chrCode x
+ OrdOp -> coerceIntCode IntRep x
+ ChrOp -> chrCode x
- Float2IntOp -> coerceFP2Int x
- Int2FloatOp -> coerceInt2FP FloatRep x
- Double2IntOp -> coerceFP2Int x
- Int2DoubleOp -> coerceInt2FP DoubleRep x
+ Float2IntOp -> coerceFP2Int x
+ Int2FloatOp -> coerceInt2FP FloatRep x
+ Double2IntOp -> coerceFP2Int x
+ Int2DoubleOp -> coerceInt2FP DoubleRep x
other_op ->
let
- fixed_x = if is_float_op -- promote to double
- then StPrim Float2DoubleOp [x]
- else x
+ fixed_x = if is_float_op -- promote to double
+ then StPrim Float2DoubleOp [x]
+ else x
in
- getRegister (StCall fn cCallConv DoubleRep [x])
+ getRegister (StCall fn cCallConv DoubleRep [fixed_x])
where
(is_float_op, fn)
= case primop of
DoubleExpOp -> (False, SLIT("exp"))
DoubleLogOp -> (False, SLIT("log"))
- DoubleSqrtOp -> (True, SLIT("sqrt"))
+ DoubleSqrtOp -> (False, SLIT("sqrt"))
DoubleSinOp -> (False, SLIT("sin"))
DoubleCosOp -> (False, SLIT("cos"))
DoubleSinhOp -> (False, SLIT("sinh"))
DoubleCoshOp -> (False, SLIT("cosh"))
DoubleTanhOp -> (False, SLIT("tanh"))
- _ -> panic ("Monadic PrimOp not handled: " ++ show primop)
+
+ other
+ -> pprPanic "getRegister(sparc,monadicprimop)"
+ (pprStixTree (StPrim primop [x]))
getRegister (StPrim primop [x, y]) -- dyadic PrimOps
= case primop of
ISraOp -> trivialCode SRA x y --was: panic "SparcGen:isra"
ISrlOp -> trivialCode SRL x y --was: panic "SparcGen:isrl"
- FloatPowerOp -> getRegister (StCall SLIT("pow") cCallConv DoubleRep [promote x, promote y])
+ FloatPowerOp -> getRegister (StCall SLIT("pow") cCallConv DoubleRep
+ [promote x, promote y])
where promote x = StPrim Float2DoubleOp [x]
- DoublePowerOp -> getRegister (StCall SLIT("pow") cCallConv DoubleRep [x, y])
--- _ -> panic "Prim op " ++ (showPrimOp primop) ++ " not handled!"
+ DoublePowerOp -> getRegister (StCall SLIT("pow") cCallConv DoubleRep
+ [x, y])
+
+ other
+ -> pprPanic "getRegister(sparc,dyadic primop)"
+ (pprStixTree (StPrim primop [x, y]))
+
where
imul_div fn x y = getRegister (StCall fn cCallConv IntRep [x, y])
OR False dst (RIImm (LO imm__2)) dst]
in
returnNat (Any PtrRep code)
+ | otherwise
+ = pprPanic "getRegister(sparc)" (pprStixTree leaf)
where
imm = maybeImm leaf
imm__2 = case imm of Just x -> x
code1 = registerCode register1 tmp1
src1 = registerName register1 tmp1
- pk2 = registerRep register2
code2 = registerCode register2 tmp2
src2 = registerName register2 tmp2
register allocator.
\begin{code}
-genJump :: StixTree{-the branch target-} -> NatM InstrBlock
+genJump :: DestInfo -> StixTree{-the branch target-} -> NatM InstrBlock
#if alpha_TARGET_ARCH
target = ImmCLbl lbl
genJump tree
- = getRegister tree `thenNat` \ register ->
+ = getRegister tree `thenNat` \ register ->
getNewRegNCG PtrRep `thenNat` \ tmp ->
let
dst = registerName register pv
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if i386_TARGET_ARCH
-genJump (StInd pk mem)
+genJump dsts (StInd pk mem)
= getAmode mem `thenNat` \ amode ->
let
code = amodeCode amode
target = amodeAddr amode
in
- returnNat (code `snocOL` JMP (OpAddr target))
+ returnNat (code `snocOL` JMP dsts (OpAddr target))
-genJump tree
+genJump dsts tree
| maybeToBool imm
- = returnNat (unitOL (JMP (OpImm target)))
+ = returnNat (unitOL (JMP dsts (OpImm target)))
| otherwise
= getRegister tree `thenNat` \ register ->
code = registerCode register tmp
target = registerName register tmp
in
- returnNat (code `snocOL` JMP (OpReg target))
+ returnNat (code `snocOL` JMP dsts (OpReg target))
where
imm = maybeImm tree
target = case imm of Just x -> x
-- ToDo:needed (WDP 96/03) ???
fn__2 = case (_HEAD_ fn) of
'.' -> ImmLit (ptext fn)
- _ -> ImmLab (ptext fn)
+ _ -> ImmLab False (ptext fn)
arg_size DF = 8
- arg_size F = 8
+ arg_size F = 4
arg_size _ = 4
------------
if (case sz of DF -> True; F -> True; _ -> False)
then returnNat (size,
code `appOL`
- toOL [SUB L (OpImm (ImmInt 8)) (OpReg esp),
+ toOL [SUB L (OpImm (ImmInt size)) (OpReg esp),
DELTA (delta-size),
- GST DF reg (AddrBaseIndex (Just esp)
+ GST sz reg (AddrBaseIndex (Just esp)
Nothing
(ImmInt 0))]
)
#endif {- i386_TARGET_ARCH -}
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if sparc_TARGET_ARCH
+{-
+ The SPARC calling convention is an absolute
+ nightmare. The first 6x32 bits of arguments are mapped into
+ %o0 through %o5, and the remaining arguments are dumped to the
+ stack, beginning at [%sp+92]. (Note that %o6 == %sp.)
+
+ If we have to put args on the stack, move %o6==%sp down by
+ the number of words to go on the stack, to ensure there's enough space.
+
+ According to Fraser and Hanson's lcc book, page 478, fig 17.2,
+ 16 words above the stack pointer is a word for the address of
+ a structure return value. I use this as a temporary location
+ for moving values from float to int regs. Certainly it isn't
+ safe to put anything in the 16 words starting at %sp, since
+ this area can get trashed at any time due to window overflows
+ caused by signal handlers.
+
+ A final complication (if the above isn't enough) is that
+ we can't blithely calculate the arguments one by one into
+ %o0 .. %o5. Consider the following nested calls:
+
+ fff a (fff b c)
+
+ Naive code moves a into %o0, and (fff b c) into %o1. Unfortunately
+ the inner call will itself use %o0, which trashes the value put there
+ in preparation for the outer call. Upshot: we need to calculate the
+ args into temporary regs, and move those to arg regs or onto the
+ stack only immediately prior to the call proper. Sigh.
+-}
genCCall fn cconv kind args
- = mapAccumLNat get_arg (allArgRegs, eXTRA_STK_ARGS_HERE) args
- `thenNat` \ ((unused,_), argCode) ->
- let
- nRegs = length allArgRegs - length unused
- call = CALL fn__2 nRegs False
- code = concatOL argCode
- in
- returnNat (code `snocOL` call `snocOL` NOP)
+ = mapNat arg_to_int_vregs args `thenNat` \ argcode_and_vregs ->
+ let (argcodes, vregss) = unzip argcode_and_vregs
+ argcode = concatOL argcodes
+ vregs = concat vregss
+ n_argRegs = length allArgRegs
+ n_argRegs_used = min (length vregs) n_argRegs
+ (move_sp_down, move_sp_up)
+ = let nn = length vregs - n_argRegs
+ + 1 -- (for the road)
+ in if nn <= 0
+ then (nilOL, nilOL)
+ else (unitOL (moveSp (-1*nn)), unitOL (moveSp (1*nn)))
+ transfer_code
+ = toOL (move_final vregs allArgRegs eXTRA_STK_ARGS_HERE)
+ call
+ = unitOL (CALL fn__2 n_argRegs_used False)
+ in
+ returnNat (argcode `appOL`
+ move_sp_down `appOL`
+ transfer_code `appOL`
+ call `appOL`
+ unitOL NOP `appOL`
+ move_sp_up)
where
- -- function names that begin with '.' are assumed to be special
- -- internally generated names like '.mul,' which don't get an
- -- underscore prefix
- -- ToDo:needed (WDP 96/03) ???
- fn__2 = case (_HEAD_ fn) of
- '.' -> ImmLit (ptext fn)
- _ -> ImmLab (ptext fn)
-
- ------------------------------------
- {- Try to get a value into a specific register (or registers) for
- a call. The SPARC calling convention is an absolute
- nightmare. The first 6x32 bits of arguments are mapped into
- %o0 through %o5, and the remaining arguments are dumped to the
- stack, beginning at [%sp+92]. (Note that %o6 == %sp.) Our
- first argument is a pair of the list of remaining argument
- registers to be assigned for this call and the next stack
- offset to use for overflowing arguments. This way,
- @get_arg@ can be applied to all of a call's arguments using
- @mapAccumL@.
- -}
- get_arg
- :: ([Reg],Int) -- Argument registers and stack offset (accumulator)
- -> StixTree -- Current argument
- -> NatM (([Reg],Int), InstrBlock) -- Updated accumulator and code
-
- -- We have to use up all of our argument registers first...
-
- get_arg (dst:dsts, offset) arg
- = getRegister arg `thenNat` \ register ->
- getNewRegNCG (registerRep register)
- `thenNat` \ tmp ->
- let
- reg = if isFloatingRep pk then tmp else dst
- code = registerCode register reg
- src = registerName register reg
- pk = registerRep register
- in
- returnNat (
- case pk of
- DoubleRep ->
- case dsts of
- [] -> ( ([], offset + 1),
- code `snocOL`
- -- conveniently put the second part in the right stack
- -- location, and load the first part into %o5
- ST DF src (spRel (offset - 1)) `snocOL`
- LD W (spRel (offset - 1)) dst
- )
- (dst__2:dsts__2)
- -> ( (dsts__2, offset),
- code `snocOL`
- ST DF src (spRel (-2)) `snocOL`
- LD W (spRel (-2)) dst `snocOL`
- LD W (spRel (-1)) dst__2
- )
- FloatRep
- -> ( (dsts, offset),
- code `snocOL`
- ST F src (spRel (-2)) `snocOL`
- LD W (spRel (-2)) dst
- )
- _ -> ( (dsts, offset),
- if isFixed register
- then code `snocOL` OR False g0 (RIReg src) dst
- else code
- )
- )
- -- Once we have run out of argument registers, we move to the
- -- stack...
-
- get_arg ([], offset) arg
- = getRegister arg `thenNat` \ register ->
- getNewRegNCG (registerRep register)
- `thenNat` \ tmp ->
- let
- code = registerCode register tmp
- src = registerName register tmp
- pk = registerRep register
- sz = primRepToSize pk
- words = if pk == DoubleRep then 2 else 1
- in
- returnNat ( ([], offset + words),
- code `snocOL` ST sz src (spRel offset) )
-
+ -- function names that begin with '.' are assumed to be special
+ -- internally generated names like '.mul,' which don't get an
+ -- underscore prefix
+ -- ToDo:needed (WDP 96/03) ???
+ fn__2 = case (_HEAD_ fn) of
+ '.' -> ImmLit (ptext fn)
+ _ -> ImmLab False (ptext fn)
+
+ -- move args from the integer vregs into which they have been
+ -- marshalled, into %o0 .. %o5, and the rest onto the stack.
+ move_final :: [Reg] -> [Reg] -> Int -> [Instr]
+
+ move_final [] _ offset -- all args done
+ = []
+
+ move_final (v:vs) [] offset -- out of aregs; move to stack
+ = ST W v (spRel offset)
+ : move_final vs [] (offset+1)
+
+ move_final (v:vs) (a:az) offset -- move into an arg (%o[0..5]) reg
+ = OR False g0 (RIReg v) a
+ : move_final vs az offset
+
+ -- generate code to calculate an argument, and move it into one
+ -- or two integer vregs.
+ arg_to_int_vregs :: StixTree -> NatM (OrdList Instr, [Reg])
+ arg_to_int_vregs arg
+ = getRegister arg `thenNat` \ register ->
+ getNewRegNCG (registerRep register) `thenNat` \ tmp ->
+ let code = registerCode register tmp
+ src = registerName register tmp
+ pk = registerRep register
+ in
+ -- the value is in src. Get it into 1 or 2 int vregs.
+ case pk of
+ DoubleRep ->
+ getNewRegNCG WordRep `thenNat` \ v1 ->
+ getNewRegNCG WordRep `thenNat` \ v2 ->
+ returnNat (
+ code `snocOL`
+ FMOV DF src f0 `snocOL`
+ ST F f0 (spRel 16) `snocOL`
+ LD W (spRel 16) v1 `snocOL`
+ ST F (fPair f0) (spRel 16) `snocOL`
+ LD W (spRel 16) v2
+ ,
+ [v1,v2]
+ )
+ FloatRep ->
+ getNewRegNCG WordRep `thenNat` \ v1 ->
+ returnNat (
+ code `snocOL`
+ ST F src (spRel 16) `snocOL`
+ LD W (spRel 16) v1
+ ,
+ [v1]
+ )
+ other ->
+ getNewRegNCG WordRep `thenNat` \ v1 ->
+ returnNat (
+ code `snocOL` OR False g0 (RIReg src) v1
+ ,
+ [v1]
+ )
#endif {- sparc_TARGET_ARCH -}
\end{code}
code2 `snocOL`
instr (primRepToSize pk) tmp1 src2 dst
in
- returnNat (Any DoubleRep code__2)
+ returnNat (Any pk code__2)
-------------
%* *
%************************************************************************
-Integer to character conversion. Where applicable, we try to do this
-in one step if the original object is in memory.
+Integer to character conversion.
\begin{code}
chrCode :: StixTree -> NatM Register
#if alpha_TARGET_ARCH
+-- TODO: This is probably wrong, but I don't know Alpha assembler.
+-- It should coerce a 64-bit value to a 32-bit value.
+
chrCode x
= getRegister x `thenNat` \ register ->
getNewRegNCG IntRep `thenNat` \ reg ->
chrCode x
= getRegister x `thenNat` \ register ->
- let
- code__2 dst = let
- code = registerCode register dst
- src = registerName register dst
- in code `appOL`
- if isFixed register && src /= dst
- then toOL [MOV L (OpReg src) (OpReg dst),
- AND L (OpImm (ImmInt 255)) (OpReg dst)]
- else unitOL (AND L (OpImm (ImmInt 255)) (OpReg src))
- in
- returnNat (Any IntRep code__2)
+ returnNat (
+ case register of
+ Fixed _ reg code -> Fixed IntRep reg code
+ Any _ code -> Any IntRep code
+ )
#endif {- i386_TARGET_ARCH -}
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if sparc_TARGET_ARCH
-chrCode (StInd pk mem)
- = getAmode mem `thenNat` \ amode ->
- let
- code = amodeCode amode
- src = amodeAddr amode
- src_off = addrOffset src 3
- src__2 = case src_off of Just x -> x
- code__2 dst = if maybeToBool src_off then
- code `snocOL` LD BU src__2 dst
- else
- code `snocOL`
- LD (primRepToSize pk) src dst `snocOL`
- AND False dst (RIImm (ImmInt 255)) dst
- in
- returnNat (Any pk code__2)
-
chrCode x
= getRegister x `thenNat` \ register ->
- getNewRegNCG IntRep `thenNat` \ reg ->
- let
- code = registerCode register reg
- src = registerName register reg
- code__2 dst = code `snocOL` AND False src (RIImm (ImmInt 255)) dst
- in
- returnNat (Any IntRep code__2)
+ returnNat (
+ case register of
+ Fixed _ reg code -> Fixed IntRep reg code
+ Any _ code -> Any IntRep code
+ )
#endif {- sparc_TARGET_ARCH -}
\end{code}