module MachMisc (
- sizeOf, primRepToSize,
+ primRepToSize,
eXTRA_STK_ARGS_HERE,
import Stix ( StixStmt(..), StixExpr(..), StixReg(..),
CodeSegment, DestInfo(..) )
import Panic ( panic )
-import GlaExts ( word2Int#, int2Word#, shiftRL#, and#, (/=#) )
import Outputable ( pprPanic, ppr, showSDoc )
-import IOExts ( trace )
import Config ( cLeadingUnderscore )
import FastTypes
+import FastString
+
+import GLAEXTS
+import TRACE ( trace )
import Maybe ( catMaybes )
\end{code}
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Size of a @PrimRep@, in bytes.
-
-\begin{code}
-sizeOf :: PrimRep -> Int{-in bytes-}
-sizeOf pr = case primRepToSize pr of
- IF_ARCH_alpha({B->1; Bu->1; {-W->2; Wu->2;-} L->4; {-SF->4;-} Q->8; TF->8},)
- IF_ARCH_i386 ({B->1; Bu->1; W->2; Wu->2; L->4; Lu->4; F->4; DF->8; F80->10},)
- IF_ARCH_sparc({B->1; Bu->1; W->4; F->4; DF->8},)
-\end{code}
-
-% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
Now the volatile saves and restores. We add the basic guys to the
list of ``user'' registers provided. Note that there are more basic
registers on the restore list, because some are reloaded from
= catMaybes (map mkCode vols)
where
mkCode mid
+ | case mid of { BaseReg -> True; _ -> False }
+ = panic "volatileSavesOrRestores:BaseReg"
| not (callerSaves mid)
= Nothing
| otherwise -- must be callee-saves ...
Just (toInteger (iBox (pow2 x#)))
}
where
- shiftr x y = shiftRL# x y
-
pow2 x# | x# ==# 1# = 0#
- | otherwise = 1# +# pow2 (w2i (i2w x# `shiftr` 1#))
+ | otherwise = 1# +# pow2 (w2i (i2w x# `shiftRL#` 1#))
\end{code}
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| VC
| VS
#endif
+ deriving Eq -- to make an assertion work
\end{code}
\begin{code}
#if sparc_TARGET_ARCH
= B -- byte (signed)
| Bu -- byte (unsigned)
+ | H -- halfword (signed, 2 bytes)
+ | Hu -- halfword (unsigned, 2 bytes)
| W -- word (4 bytes)
| F -- IEEE single-precision floating pt
| DF -- IEEE single-precision floating pt
primRepToSize CharRep = IF_ARCH_alpha(L, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize Int8Rep = IF_ARCH_alpha(B, IF_ARCH_i386(B, IF_ARCH_sparc(B, )))
-primRepToSize Int16Rep = IF_ARCH_alpha(err,IF_ARCH_i386(W, IF_ARCH_sparc(err,)))
+primRepToSize Int16Rep = IF_ARCH_alpha(err,IF_ARCH_i386(W, IF_ARCH_sparc(H, )))
where err = primRepToSize_fail "Int16Rep"
primRepToSize Int32Rep = IF_ARCH_alpha(L, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize Word8Rep = IF_ARCH_alpha(Bu, IF_ARCH_i386(Bu, IF_ARCH_sparc(Bu, )))
-primRepToSize Word16Rep = IF_ARCH_alpha(err,IF_ARCH_i386(Wu, IF_ARCH_sparc(err,)))
+primRepToSize Word16Rep = IF_ARCH_alpha(err,IF_ARCH_i386(Wu, IF_ARCH_sparc(Hu, )))
where err = primRepToSize_fail "Word16Rep"
primRepToSize Word32Rep = IF_ARCH_alpha(L, IF_ARCH_i386(Lu, IF_ARCH_sparc(W, )))
primRepToSize AddrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize FloatRep = IF_ARCH_alpha(TF, IF_ARCH_i386(F, IF_ARCH_sparc(F, )))
primRepToSize DoubleRep = IF_ARCH_alpha(TF, IF_ARCH_i386(DF, IF_ARCH_sparc(DF, )))
-primRepToSize ArrayRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
-primRepToSize ByteArrayRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
-primRepToSize PrimPtrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
-primRepToSize WeakPtrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
-primRepToSize ForeignObjRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
-primRepToSize BCORep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize StablePtrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
-primRepToSize StableNameRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
-primRepToSize ThreadIdRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize Word64Rep = primRepToSize_fail "Word64Rep"
primRepToSize Int64Rep = primRepToSize_fail "Int64Rep"
++ "Workaround: use -fvia-C.\n\t"
++ "Perhaps you should report it as a GHC bug,\n\t"
++ "to glasgow-haskell-bugs@haskell.org.")
-
\end{code}
%************************************************************************
\begin{code}
data Instr
- = COMMENT FAST_STRING -- comment pseudo-op
+ = COMMENT FastString -- comment pseudo-op
| SEGMENT CodeSegment -- {data,text} segment pseudo-op
| LABEL CLabel -- global label pseudo-op
| ASCII Bool -- True <=> needs backslash conversion
| SUB Size Operand Operand
| IMUL Size Operand Operand -- signed int mul
| MUL Size Operand Operand -- unsigned int mul
+ | IMUL64 Reg Reg -- 32 x 32 -> 64 signed mul
+ -- operand1:operand2 := (operand1[31:0] *signed operand2[31:0])
-- Quotient and remainder. SEE comment above -- these are not
-- real x86 insns; instead they are expanded when printed
| GSUB Size Reg Reg Reg -- src1, src2, dst
| GMUL Size Reg Reg Reg -- src1, src2, dst
- | GCMP Size Reg Reg -- src1, src2
+ -- FP compare. Cond must be `elem` [EQQ, NE, LE, LTT, GE, GTT]
+ -- Compare src1 with src2; set the Zero flag iff the numbers are
+ -- comparable and the comparison is True. Subsequent code must
+ -- test the %eflags zero flag regardless of the supplied Cond.
+ | GCMP Cond Reg Reg -- src1, src2
| GABS Size Reg Reg -- src, dst
| GNEG Size Reg Reg -- src, dst
| JMP DestInfo Operand -- possible dests, target
| JXX Cond CLabel -- target
- | CALL Imm
+ | CALL (Either Imm Reg)
-- Other things.
| ADD Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
| SUB Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
+ | UMUL Bool Reg RI Reg -- cc?, src1, src2, dst
+ | SMUL Bool Reg RI Reg -- cc?, src1, src2, dst
+ | RDY Reg -- move contents of Y register to reg
-- Simple bit-twiddling.
| BF Cond Bool Imm -- cond, annul?, target
| JMP DestInfo MachRegsAddr -- target
- | CALL Imm Int Bool -- target, args, terminal
+ | CALL (Either Imm Reg) Int Bool -- target, args, terminal
data RI = RIReg Reg
| RIImm Imm