X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FnativeGen%2FMachInstrs.hs;h=0f718d3ceacda83eb0f5c37ad133444084b0a505;hb=927eebacf4d6143067f7712aa0d4a3894b0bc044;hp=4cfcc178bf71cee62b79349b86527c6870ad6628;hpb=b4d045ae655e5eae25b88917cfe75d7dc7689c21;p=ghc-hetmet.git diff --git a/ghc/compiler/nativeGen/MachInstrs.hs b/ghc/compiler/nativeGen/MachInstrs.hs index 4cfcc17..0f718d3 100644 --- a/ghc/compiler/nativeGen/MachInstrs.hs +++ b/ghc/compiler/nativeGen/MachInstrs.hs @@ -14,28 +14,25 @@ module MachInstrs ( -- * Machine instructions Instr(..), - Cond(..), -#if !powerpc_TARGET_ARCH && !i386_TARGET_ARCH + Cond(..), condUnsigned, condToSigned, condToUnsigned, + +#if !powerpc_TARGET_ARCH && !i386_TARGET_ARCH && !x86_64_TARGET_ARCH Size(..), machRepSize, #endif RI(..), -#if i386_TARGET_ARCH +#if i386_TARGET_ARCH || x86_64_TARGET_ARCH Operand(..), +#endif +#if i386_TARGET_ARCH i386_insert_ffrees, #endif #if sparc_TARGET_ARCH riZero, fpRelEA, moveSp, fPair, #endif -#if powerpc_TARGET_ARCH - condUnsigned, condToSigned, -#endif - DestInfo(..), hasDestInfo, pprDests, - ) where #include "HsVersions.h" -#include "../includes/ghcconfig.h" import MachRegs import Cmm @@ -43,8 +40,8 @@ import MachOp ( MachRep(..) ) import CLabel ( CLabel, pprCLabel ) import Panic ( panic ) import Outputable -import Config ( cLeadingUnderscore ) import FastString +import Constants ( wORD_SIZE ) import GLAEXTS @@ -73,7 +70,7 @@ data Cond | ULE -- For CMP only | ULT -- For CMP only #endif -#if i386_TARGET_ARCH +#if i386_TARGET_ARCH || x86_64_TARGET_ARCH = ALWAYS -- What's really used? ToDo | EQQ | GE @@ -89,6 +86,8 @@ data Cond | POS | CARRY | OFLO + | PARITY + | NOTPARITY #endif #if sparc_TARGET_ARCH = ALWAYS -- What's really used? ToDo @@ -123,6 +122,23 @@ data Cond #endif deriving Eq -- to make an assertion work +condUnsigned GU = True +condUnsigned LU = True +condUnsigned GEU = True +condUnsigned LEU = True +condUnsigned _ = False + +condToSigned GU = GTT +condToSigned LU = LTT +condToSigned GEU = GE +condToSigned LEU = LE +condToSigned x = x + +condToUnsigned GTT = GU +condToUnsigned LTT = LU +condToUnsigned GE = GEU +condToUnsigned LE = LEU +condToUnsigned x = x -- ----------------------------------------------------------------------------- -- Sizes on this architecture @@ -130,7 +146,7 @@ data Cond -- ToDo: it's not clear to me that we need separate signed-vs-unsigned sizes -- here. I've removed them from the x86 version, we'll see what happens --SDM -#if !powerpc_TARGET_ARCH && !i386_TARGET_ARCH +#if !powerpc_TARGET_ARCH && !i386_TARGET_ARCH && !x86_64_TARGET_ARCH data Size #if alpha_TARGET_ARCH = B -- byte @@ -364,7 +380,7 @@ bit or 64 bit precision. --SDM 1/2003 -} -#if i386_TARGET_ARCH +#if i386_TARGET_ARCH || x86_64_TARGET_ARCH -- data Instr continues... @@ -372,6 +388,9 @@ bit or 64 bit precision. | MOV MachRep Operand Operand | MOVZxL MachRep Operand Operand -- size is the size of operand 1 | MOVSxL MachRep Operand Operand -- size is the size of operand 1 + -- x86_64 note: plain mov into a 32-bit register always zero-extends + -- into the 64-bit reg, in contrast to the 8 and 16-bit movs which + -- don't affect the high bits of the register. -- Load effective address (also a very useful three-operand add instruction :-) | LEA MachRep Operand Operand @@ -380,11 +399,10 @@ bit or 64 bit precision. | ADD MachRep Operand Operand | ADC MachRep Operand Operand | SUB MachRep Operand Operand - | IMUL MachRep Operand Operand -- signed int mul - | MUL MachRep Operand Operand -- unsigned int mul - | IMUL64 Reg Reg - -- operand1:operand2 := (operand1[31:0] *signed operand2[31:0]) + | MUL MachRep Operand Operand + | IMUL MachRep Operand Operand -- signed int mul + | IMUL2 MachRep Operand -- %edx:%eax = operand * %eax | DIV MachRep Operand -- eax := eax:edx/op, edx := eax:edx%op | IDIV MachRep Operand -- ditto, but signed @@ -404,6 +422,7 @@ bit or 64 bit precision. | BT MachRep Imm Operand | NOP +#if i386_TARGET_ARCH -- Float Arithmetic. -- Note that we cheat by treating G{ABS,MOV,NEG} of doubles @@ -443,6 +462,32 @@ bit or 64 bit precision. | GTAN MachRep Reg Reg -- src, dst | GFREE -- do ffree on all x86 regs; an ugly hack +#endif + +#if x86_64_TARGET_ARCH +-- SSE2 floating point: we use a restricted set of the available SSE2 +-- instructions for floating-point. + + -- use MOV for moving (either movss or movsd (movlpd better?)) + + | CVTSS2SD Reg Reg -- F32 to F64 + | CVTSD2SS Reg Reg -- F64 to F32 + | CVTSS2SI Operand Reg -- F32 to I32/I64 (with rounding) + | CVTSD2SI Operand Reg -- F64 to I32/I64 (with rounding) + | CVTSI2SS Operand Reg -- I32/I64 to F32 + | CVTSI2SD Operand Reg -- I32/I64 to F64 + + -- use ADD & SUB for arithmetic. In both cases, operands + -- are Operand Reg. + + -- SSE2 floating-point division: + | FDIV MachRep Operand Operand -- divisor, dividend(dst) + + -- use CMP for comparisons. ucomiss and ucomisd instructions + -- compare single/double prec floating point respectively. + + | SQRT MachRep Operand Reg -- src, dst +#endif -- Comparison | TEST MachRep Operand Operand @@ -453,24 +498,37 @@ bit or 64 bit precision. | PUSH MachRep Operand | POP MachRep Operand -- both unused (SDM): - -- | PUSHA - -- | POPA + -- | PUSHA + -- | POPA -- Jumping around. | JMP Operand | JXX Cond BlockId -- includes unconditional branches | JMP_TBL Operand [BlockId] -- table jump - | CALL (Either Imm Reg) + | CALL (Either Imm Reg) [Reg] -- Other things. - | CLTD -- sign extend %eax into %edx:%eax + | CLTD MachRep -- sign extend %eax into %edx:%eax + + | FETCHGOT Reg -- pseudo-insn for ELF position-independent code + -- pretty-prints as + -- call 1f + -- 1: popl %reg + -- addl __GLOBAL_OFFSET_TABLE__+.-1b, %reg + | FETCHPC Reg -- pseudo-insn for Darwin position-independent code + -- pretty-prints as + -- call 1f + -- 1: popl %reg + data Operand = OpReg Reg -- register | OpImm Imm -- immediate value | OpAddr AddrMode -- memory reference +#endif /* i386 or x86_64 */ +#if i386_TARGET_ARCH i386_insert_ffrees :: [Instr] -> [Instr] i386_insert_ffrees insns | any is_G_instr insns @@ -480,9 +538,9 @@ i386_insert_ffrees insns ffree_before_nonlocal_transfers insn = case insn of - CALL _ -> [GFREE, insn] - JMP _ -> [GFREE, insn] - other -> [insn] + CALL _ _ -> [GFREE, insn] + JMP _ -> [GFREE, insn] + other -> [insn] -- if you ever add a new FP insn to the fake x86 FP insn set, @@ -490,18 +548,17 @@ ffree_before_nonlocal_transfers insn is_G_instr :: Instr -> Bool is_G_instr instr = case instr of - GMOV _ _ -> True; GLD _ _ _ -> True; GST _ _ _ -> True; - GLDZ _ -> True; GLD1 _ -> True; - GFTOI _ _ -> True; GDTOI _ _ -> True; - GITOF _ _ -> True; GITOD _ _ -> True; + GMOV _ _ -> True; GLD _ _ _ -> True; GST _ _ _ -> True + GLDZ _ -> True; GLD1 _ -> True + GFTOI _ _ -> True; GDTOI _ _ -> True + GITOF _ _ -> True; GITOD _ _ -> True GADD _ _ _ _ -> True; GDIV _ _ _ _ -> True GSUB _ _ _ _ -> True; GMUL _ _ _ _ -> True GCMP _ _ _ -> True; GABS _ _ _ -> True GNEG _ _ _ -> True; GSQRT _ _ _ -> True - GSIN _ _ _ -> True; GCOS _ _ _ -> True; GTAN _ _ _ -> True; + GSIN _ _ _ -> True; GCOS _ _ _ -> True; GTAN _ _ _ -> True GFREE -> panic "is_G_instr: GFREE (!)" other -> False - #endif /* i386_TARGET_ARCH */ @@ -555,12 +612,9 @@ is_G_instr instr | BI Cond Bool Imm -- cond, annul?, target | BF Cond Bool Imm -- cond, annul?, target - | JMP DestInfo AddrMode -- target + | JMP AddrMode -- target | CALL (Either Imm Reg) Int Bool -- target, args, terminal -data RI = RIReg Reg - | RIImm Imm - riZero :: RI -> Bool riZero (RIImm (ImmInt 0)) = True @@ -573,12 +627,12 @@ riZero _ = False -- alas -- can't have fpRelEA here because of module dependencies. fpRelEA :: Int -> Reg -> Instr fpRelEA n dst - = ADD False False fp (RIImm (ImmInt (n * BYTES_PER_WORD))) dst + = ADD False False fp (RIImm (ImmInt (n * wORD_SIZE))) dst -- Code to shift the stack pointer by n words. moveSp :: Int -> Instr moveSp n - = ADD False False sp (RIImm (ImmInt (n * BYTES_PER_WORD))) sp + = ADD False False sp (RIImm (ImmInt (n * wORD_SIZE))) sp -- Produce the second-half-of-a-double register given the first half. fPair :: Reg -> Reg @@ -665,33 +719,4 @@ fPair other = pprPanic "fPair(sparc NCG)" (ppr other) | FETCHPC Reg -- pseudo-instruction: -- bcl to next insn, mflr reg -condUnsigned GU = True -condUnsigned LU = True -condUnsigned GEU = True -condUnsigned LEU = True -condUnsigned _ = False - -condToSigned GU = GTT -condToSigned LU = LTT -condToSigned GEU = GE -condToSigned LEU = LE -condToSigned x = x #endif /* powerpc_TARGET_ARCH */ - - --- ----------------------------------------------------------------------------- --- DestInfo - --- ToDo: might not be needed anymore --SDM - --- used by insnFuture in RegAllocInfo.lhs -data DestInfo - = NoDestInfo -- no supplied dests; infer from context - | DestInfo [CLabel] -- precisely these dests and no others - -hasDestInfo NoDestInfo = False -hasDestInfo (DestInfo _) = True - -pprDests :: DestInfo -> SDoc -pprDests NoDestInfo = text "NoDestInfo" -pprDests (DestInfo dsts) = brackets (hsep (map pprCLabel dsts))