Commit 97906cfc authored by wolfgang's avatar wolfgang
Browse files

[project @ 2002-10-12 23:28:48 by wolfgang]

The Native Code Generator for PowerPC.
Still to be done:
*) Proper support of Floats and Doubles
   currently it seems to work, but it's just guesswork.
*) Some missing operations, only needed for -O, AFAICT.
*) Mach-O dynamic linker stub generation.
   (can't import foreign functions from dynamic libraries,
   and it might fail for big programs)
parent 9506b93c
This diff is collapsed.
......@@ -32,6 +32,10 @@ module MachMisc (
#endif
#if sparc_TARGET_ARCH
RI(..), riZero, fpRelEA, moveSp, fPair
#endif
#if powerpc_TARGET_ARCH
, RI(..)
, condUnsigned, condToSigned
#endif
) where
......@@ -90,7 +94,7 @@ where do we start putting the rest of them?
\begin{code}
eXTRA_STK_ARGS_HERE :: Int
eXTRA_STK_ARGS_HERE
= IF_ARCH_alpha(0, IF_ARCH_i386(23{-6x4bytes-}, IF_ARCH_sparc(23,???)))
= IF_ARCH_alpha(0, IF_ARCH_i386(23{-6x4bytes-}, IF_ARCH_sparc(23, IF_ARCH_powerpc(24,???))))
\end{code}
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
......@@ -234,6 +238,19 @@ data Cond
| POS
| VC
| VS
#endif
#if powerpc_TARGET_ARCH
= ALWAYS
| EQQ
| GE
| GEU
| GTT
| GU
| LE
| LEU
| LTT
| LU
| NE
#endif
deriving Eq -- to make an assertion work
\end{code}
......@@ -264,7 +281,7 @@ data Size
| DF -- IEEE single-precision floating pt
| F80 -- Intel 80-bit internal FP format; only used for spilling
#endif
#if sparc_TARGET_ARCH
#if sparc_TARGET_ARCH || powerpc_TARGET_ARCH
= B -- byte (signed)
| Bu -- byte (unsigned)
| H -- halfword (signed, 2 bytes)
......@@ -276,28 +293,28 @@ data Size
primRepToSize :: PrimRep -> Size
primRepToSize PtrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize CodePtrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize DataPtrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize RetRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize CostCentreRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize CharRep = IF_ARCH_alpha(L, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize PtrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, IF_ARCH_powerpc(W, ))))
primRepToSize CodePtrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, IF_ARCH_powerpc(W, ))))
primRepToSize DataPtrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, IF_ARCH_powerpc(W, ))))
primRepToSize RetRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, IF_ARCH_powerpc(W, ))))
primRepToSize CostCentreRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, IF_ARCH_powerpc(W, ))))
primRepToSize CharRep = IF_ARCH_alpha(L, IF_ARCH_i386(L, IF_ARCH_sparc(W, IF_ARCH_powerpc(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(H, )))
primRepToSize Int8Rep = IF_ARCH_alpha(B, IF_ARCH_i386(B, IF_ARCH_sparc(B, IF_ARCH_powerpc(B, ))))
primRepToSize Int16Rep = IF_ARCH_alpha(err,IF_ARCH_i386(W, IF_ARCH_sparc(H, IF_ARCH_powerpc(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(Hu, )))
primRepToSize Int32Rep = IF_ARCH_alpha(L, IF_ARCH_i386(L, IF_ARCH_sparc(W, IF_ARCH_powerpc(W, ))))
primRepToSize Word8Rep = IF_ARCH_alpha(Bu, IF_ARCH_i386(Bu, IF_ARCH_sparc(Bu, IF_ARCH_powerpc(Bu, ))))
primRepToSize Word16Rep = IF_ARCH_alpha(err,IF_ARCH_i386(Wu, IF_ARCH_sparc(Hu, IF_ARCH_powerpc(Hu, ))))
where err = primRepToSize_fail "Word16Rep"
primRepToSize Word32Rep = IF_ARCH_alpha(L, IF_ARCH_i386(Lu, IF_ARCH_sparc(W, )))
primRepToSize Word32Rep = IF_ARCH_alpha(L, IF_ARCH_i386(Lu, IF_ARCH_sparc(W, IF_ARCH_powerpc(W, ))))
primRepToSize IntRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize WordRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, 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 StablePtrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, )))
primRepToSize IntRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, IF_ARCH_powerpc(W, ))))
primRepToSize WordRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, IF_ARCH_powerpc(W, ))))
primRepToSize AddrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, IF_ARCH_powerpc(W, ))))
primRepToSize FloatRep = IF_ARCH_alpha(TF, IF_ARCH_i386(F, IF_ARCH_sparc(F, IF_ARCH_powerpc(F, ))))
primRepToSize DoubleRep = IF_ARCH_alpha(TF, IF_ARCH_i386(DF, IF_ARCH_sparc(DF, IF_ARCH_powerpc(DF, ))))
primRepToSize StablePtrRep = IF_ARCH_alpha(Q, IF_ARCH_i386(L, IF_ARCH_sparc(W, IF_ARCH_powerpc(W, ))))
primRepToSize Word64Rep = primRepToSize_fail "Word64Rep"
primRepToSize Int64Rep = primRepToSize_fail "Int64Rep"
......@@ -700,3 +717,67 @@ fPair (RealReg n) | n >= 32 && n `mod` 2 == 0 = RealReg (n+1)
fPair other = pprPanic "fPair(sparc NCG)" (ppr other)
#endif {- sparc_TARGET_ARCH -}
\end{code}
\begin{code}
#ifdef powerpc_TARGET_ARCH
-- data Instr continues...
-- Loads and stores.
| LD Size Reg MachRegsAddr -- size, dst, src
| ST Size Reg MachRegsAddr -- size, src, dst
| STU Size Reg MachRegsAddr -- size, src, dst
| LIS Reg Imm -- dst, src
| LI Reg Imm -- dst, src
| MR Reg Reg -- dst, src -- also for fmr
| CMP Size Reg RI --- size, src1, src2
| CMPL Size Reg RI --- size, src1, src2
| BCC Cond CLabel
| MTCTR Reg
| BCTR
| BL Imm [Reg] -- with list of argument regs
| BCTRL [Reg]
| ADD Reg Reg RI -- dst, src1, src2
| SUBF Reg Reg RI -- dst, src1, src2
| MULLW Reg Reg RI
| DIVW Reg Reg Reg
| DIVWU Reg Reg Reg
| AND Reg Reg RI -- dst, src1, src2
| OR Reg Reg RI -- dst, src1, src2
| XOR Reg Reg RI -- dst, src1, src2
| NEG Reg Reg
| NOT Reg Reg
| SLW Reg Reg RI
| SRW Reg Reg RI
| SRAW Reg Reg RI
| FADD Size Reg Reg Reg
| FSUB Size Reg Reg Reg
| FMUL Size Reg Reg Reg
| FDIV Size Reg Reg Reg
| FCMP Reg Reg
data RI = RIReg Reg
| RIImm Imm
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 -}
\end{code}
......@@ -49,6 +49,13 @@ module MachRegs (
, fpRel, gReg, iReg, lReg, oReg, largeOffsetError
, fp, sp, g0, g1, g2, o0, o1, f0, f6, f8, f26, f27
#endif
#if powerpc_TARGET_ARCH
, allFPArgRegs
, fits16Bits
, sp
, r3, r4, r27, r28
, f1, f20, f21
#endif
) where
......@@ -83,7 +90,11 @@ data Imm
IF_ARCH_sparc(
| LO Imm -- Possible restrictions...
| HI Imm
,)
,IF_ARCH_powerpc(
| LO Imm
| HI Imm
| HA Imm -- high halfword adjusted
,))
strImmLit s = ImmLit (text s)
\end{code}
......@@ -111,6 +122,11 @@ type Displacement = Imm
| AddrRegImm Reg Imm
#endif
#if powerpc_TARGET_ARCH
= AddrRegReg Reg Reg
| AddrRegImm Reg Imm
#endif
addrOffset :: MachRegsAddr -> Int -> Maybe MachRegsAddr
addrOffset addr off
......@@ -143,6 +159,23 @@ addrOffset addr off
_ -> Nothing
#endif {-sparc-}
#if powerpc_TARGET_ARCH
AddrRegImm r (ImmInt n)
| fits16Bits n2 -> Just (AddrRegImm r (ImmInt n2))
| otherwise -> Nothing
where n2 = n + off
AddrRegImm r (ImmInteger n)
| fits16Bits n2 -> Just (AddrRegImm r (ImmInt (fromInteger n2)))
| otherwise -> Nothing
where n2 = n + toInteger off
AddrRegReg r (RealReg 0)
| fits16Bits off -> Just (AddrRegImm r (ImmInt off))
| otherwise -> Nothing
_ -> Nothing
#endif {-powerpc-}
-----------------
#if alpha_TARGET_ARCH
......@@ -165,6 +198,11 @@ largeOffsetError i
"\nworkaround: use -fvia-C on this module.\n")
#endif {-sparc-}
#if powerpc_TARGET_ARCH
fits16Bits :: Integral a => a -> Bool
fits16Bits x = x >= -32768 && x < 32768
#endif
\end{code}
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
......@@ -503,6 +541,38 @@ f1 = RealReg (fReg 1)
#endif
\end{code}
The PowerPC has 64 registers of interest; 32 integer registers and 32 floating
point registers.
\begin{code}
#if powerpc_TARGET_ARCH
fReg :: Int -> Int
fReg x = (32 + x)
regClass (VirtualRegI u) = RcInteger
regClass (VirtualRegF u) = RcFloat
regClass (VirtualRegD u) = RcDouble
regClass (RealReg i) | i < 32 = RcInteger
| otherwise = RcDouble
-- | i < nCG_FirstFloatReg = RcDouble
-- | otherwise = RcFloat
showReg :: Int -> String
showReg n
| n >= 0 && n <= 31 = "%r" ++ show n
| n >= 32 && n <= 63 = "%f" ++ show (n - 32)
| otherwise = "%unknown_powerpc_real_reg_" ++ show n
sp = RealReg 1
r3 = RealReg 3
r4 = RealReg 4
r27 = RealReg 27
r28 = RealReg 28
f1 = RealReg $ fReg 1
f20 = RealReg $ fReg 20
f21 = RealReg $ fReg 21
#endif
\end{code}
Redefine the literals used for machine-registers with non-numeric
names in the header files. Gag me with a spoon, eh?
\begin{code}
......@@ -622,7 +692,73 @@ names in the header files. Gag me with a spoon, eh?
#define f29 61
#define f30 62
#define f31 63
#endif
#if powerpc_TARGET_ARCH
#define r0 0
#define r1 1
#define r2 2
#define r3 3
#define r4 4
#define r5 5
#define r6 6
#define r7 7
#define r8 8
#define r9 9
#define r10 10
#define r11 11
#define r12 12
#define r13 13
#define r14 14
#define r15 15
#define r16 16
#define r17 17
#define r18 18
#define r19 19
#define r20 20
#define r21 21
#define r22 22
#define r23 23
#define r24 24
#define r25 25
#define r26 26
#define r27 27
#define r28 28
#define r29 29
#define r30 30
#define r31 31
#define f0 32
#define f1 33
#define f2 34
#define f3 35
#define f4 36
#define f5 37
#define f6 38
#define f7 39
#define f8 40
#define f9 41
#define f10 42
#define f11 43
#define f12 44
#define f13 45
#define f14 46
#define f15 47
#define f16 48
#define f17 49
#define f18 50
#define f19 51
#define f20 52
#define f21 53
#define f22 54
#define f23 55
#define f24 56
#define f25 57
#define f26 58
#define f27 59
#define f28 60
#define f29 61
#define f30 62
#define f31 63
#endif
\end{code}
......@@ -832,7 +968,8 @@ allMachRegNos
IF_ARCH_sparc( ([0..31]
++ [f0,f2 .. nCG_FirstFloatReg-1]
++ [nCG_FirstFloatReg .. f31]),
)))
IF_ARCH_powerpc([0..63],
))))
-- allocatableRegs is allMachRegNos with the fixed-use regs removed.
-- i.e., these are the regs for which we are prepared to allow the
-- register allocator to attempt to map VRegs to.
......@@ -865,6 +1002,9 @@ callClobberedRegs
[gReg i | i <- [1..7]] ++
[fReg i | i <- [0..31]] )
#endif {- sparc_TARGET_ARCH -}
#if powerpc_TARGET_ARCH
map RealReg ([0..12] ++ map fReg [0..13])
#endif {- powerpc_TARGET_ARCH -}
-------------------------------
-- argRegs is the set of regs which are read for an n-argument call to C.
......@@ -899,6 +1039,19 @@ argRegs 6 = map (RealReg . oReg) [0,1,2,3,4,5]
argRegs _ = panic "MachRegs.argRegs(sparc): don't know about >6 arguments!"
#endif {- sparc_TARGET_ARCH -}
#if powerpc_TARGET_ARCH
argRegs 0 = []
argRegs 1 = map RealReg [3]
argRegs 2 = map RealReg [3,4]
argRegs 3 = map RealReg [3..5]
argRegs 4 = map RealReg [3..6]
argRegs 5 = map RealReg [3..7]
argRegs 6 = map RealReg [3..8]
argRegs 7 = map RealReg [3..9]
argRegs 8 = map RealReg [3..10]
argRegs _ = panic "MachRegs.argRegs(powerpc): don't know about >8 arguments!"
#endif {- powerpc_TARGET_ARCH -}
-------------------------------
-- all of the arg regs ??
#if alpha_TARGET_ARCH
......@@ -915,6 +1068,13 @@ allArgRegs = map RealReg [oReg i | i <- [0..5]]
allArgRegs :: [Reg]
allArgRegs = panic "MachRegs.allArgRegs(x86): should not be used!"
#endif
#if powerpc_TARGET_ARCH
allArgRegs :: [Reg]
allArgRegs = map RealReg [3..10]
allFPArgRegs :: [Reg]
allFPArgRegs = map (RealReg . fReg) [1..13]
#endif {- powerpc_TARGET_ARCH -}
\end{code}
\begin{code}
......@@ -946,6 +1106,15 @@ freeReg f0 = fastBool False -- %f0/%f1 are the C fp return registers.
freeReg f1 = fastBool False
#endif
#if powerpc_TARGET_ARCH
freeReg 0 = fastBool False -- Hack: r0 can't be used in all insns, but it's actually free
freeReg 1 = fastBool False -- The Stack Pointer
#if !darwin_TARGET_OS
-- most non-darwin powerpc OSes use r2 as a TOC pointer or something like that
freeReg 2 = fastBool False
#endif
#endif
#ifdef REG_Base
freeReg REG_Base = fastBool False
#endif
......
......@@ -65,6 +65,11 @@ you will screw up the layout where they are used in case expressions!
# define BYTES_PER_WORD_STR "4"
#endif
#if powerpc_TARGET_ARCH
# define BYTES_PER_WORD 4
# define BYTES_PER_WORD_STR "4"
#endif
---------------------------------------------
#if alpha_TARGET_ARCH
......@@ -142,4 +147,16 @@ you will screw up the layout where they are used in case expressions!
# define IF_OS_solaris2(x,y) y
#endif
---------------------------------------------
#if powerpc_TARGET_ARCH
# define IF_ARCH_powerpc(x,y) x
#else
# define IF_ARCH_powerpc(x,y) y
#endif
-- - - - - - - - - - - - - - - - - - - - - -
#if darwin_TARGET_OS
# define IF_OS_darwin(x,y) x
#else
# define IF_OS_darwin(x,y) y
#endif
---------------------------------------------
#endif
......@@ -176,6 +176,45 @@ pprReg IF_ARCH_i386(s,) r
_ -> SLIT("very naughty sparc register")
})
#endif
#if powerpc_TARGET_ARCH
ppr_reg_no :: Int -> Doc
ppr_reg_no i = ptext
(case i of {
0 -> SLIT("r0"); 1 -> SLIT("r1");
2 -> SLIT("r2"); 3 -> SLIT("r3");
4 -> SLIT("r4"); 5 -> SLIT("r5");
6 -> SLIT("r6"); 7 -> SLIT("r7");
8 -> SLIT("r8"); 9 -> SLIT("r9");
10 -> SLIT("r10"); 11 -> SLIT("r11");
12 -> SLIT("r12"); 13 -> SLIT("r13");
14 -> SLIT("r14"); 15 -> SLIT("r15");
16 -> SLIT("r16"); 17 -> SLIT("r17");
18 -> SLIT("r18"); 19 -> SLIT("r19");
20 -> SLIT("r20"); 21 -> SLIT("r21");
22 -> SLIT("r22"); 23 -> SLIT("r23");
24 -> SLIT("r24"); 25 -> SLIT("r25");
26 -> SLIT("r26"); 27 -> SLIT("r27");
28 -> SLIT("r28"); 29 -> SLIT("r29");
30 -> SLIT("r30"); 31 -> SLIT("r31");
32 -> SLIT("f0"); 33 -> SLIT("f1");
34 -> SLIT("f2"); 35 -> SLIT("f3");
36 -> SLIT("f4"); 37 -> SLIT("f5");
38 -> SLIT("f6"); 39 -> SLIT("f7");
40 -> SLIT("f8"); 41 -> SLIT("f9");
42 -> SLIT("f10"); 43 -> SLIT("f11");
44 -> SLIT("f12"); 45 -> SLIT("f13");
46 -> SLIT("f14"); 47 -> SLIT("f15");
48 -> SLIT("f16"); 49 -> SLIT("f17");
50 -> SLIT("f18"); 51 -> SLIT("f19");
52 -> SLIT("f20"); 53 -> SLIT("f21");
54 -> SLIT("f22"); 55 -> SLIT("f23");
56 -> SLIT("f24"); 57 -> SLIT("f25");
58 -> SLIT("f26"); 59 -> SLIT("f27");
60 -> SLIT("f28"); 61 -> SLIT("f29");
62 -> SLIT("f30"); 63 -> SLIT("f31");
_ -> SLIT("very naughty powerpc register")
})
#endif
\end{code}
%************************************************************************
......@@ -230,6 +269,15 @@ pprStSize x = ptext (case x of
W -> SLIT("")
F -> SLIT("")
DF -> SLIT("d")
#endif
#if powerpc_TARGET_ARCH
B -> SLIT("b")
Bu -> SLIT("b")
H -> SLIT("h")
Hu -> SLIT("h")
W -> SLIT("w")
F -> SLIT("fs")
DF -> SLIT("fd")
#endif
)
\end{code}
......@@ -273,6 +321,14 @@ pprCond c = ptext (case c of {
LEU -> SLIT("leu"); NE -> SLIT("ne");
NEG -> SLIT("neg"); POS -> SLIT("pos");
VC -> SLIT("vc"); VS -> SLIT("vs")
#endif
#if powerpc_TARGET_ARCH
ALWAYS -> SLIT("");
EQQ -> SLIT("eq"); NE -> SLIT("ne");
LTT -> SLIT("lt"); GE -> SLIT("ge");
GTT -> SLIT("gt"); LE -> SLIT("le");
LU -> SLIT("lt"); GEU -> SLIT("ge");
GU -> SLIT("gt"); LEU -> SLIT("le");
#endif
})
\end{code}
......@@ -309,6 +365,22 @@ pprImm (HI i)
where
pp_hi = text "%hi("
#endif
#if powerpc_TARGET_ARCH
pprImm (LO i)
= hcat [ pp_lo, pprImm i, rparen ]
where
pp_lo = text "lo16("
pprImm (HI i)
= hcat [ pp_hi, pprImm i, rparen ]
where
pp_hi = text "hi16("
pprImm (HA i)
= hcat [ pp_ha, pprImm i, rparen ]
where
pp_ha = text "ha16("
#endif
\end{code}
%************************************************************************
......@@ -375,6 +447,8 @@ pprAddr (AddrRegImm r1 (ImmInt i))
pprAddr (AddrRegImm r1 (ImmInteger i))
| i == 0 = pprReg r1
| not (fits13Bits i) = largeOffsetError i
-------------------
| otherwise = hcat [ pprReg r1, pp_sign, integer i ]
where
pp_sign = if i > 0 then char '+' else empty
......@@ -382,6 +456,14 @@ pprAddr (AddrRegImm r1 (ImmInteger i))
pprAddr (AddrRegImm r1 imm)
= hcat [ pprReg r1, char '+', pprImm imm ]
#endif
#if powerpc_TARGET_ARCH
pprAddr (AddrRegReg r1 r2)
= error "PprMach.pprAddr (AddrRegReg) unimplemented"
pprAddr (AddrRegImm r1 (ImmInt i)) = hcat [ int i, char '(', pprReg r1, char ')' ]
pprAddr (AddrRegImm r1 (ImmInteger i)) = hcat [ integer i, char '(', pprReg r1, char ')' ]
pprAddr (AddrRegImm r1 imm) = hcat [ pprImm imm, char '(', pprReg r1, char ')' ]
#endif
\end{code}
%************************************************************************
......@@ -398,7 +480,8 @@ pprInstr (COMMENT s)
= IF_ARCH_alpha( ((<>) (ptext SLIT("\t# ")) (ftext s))
,IF_ARCH_sparc( ((<>) (ptext SLIT("! ")) (ftext s))
,IF_ARCH_i386( ((<>) (ptext SLIT("# ")) (ftext s))
,)))
,IF_ARCH_powerpc( ((<>) (ptext SLIT("; ")) (ftext s))
,))))
pprInstr (DELTA d)
= pprInstr (COMMENT (mkFastString ("\tdelta = " ++ show d)))
......@@ -407,21 +490,24 @@ pprInstr (SEGMENT TextSegment)
= IF_ARCH_alpha(ptext SLIT("\t.text\n\t.align 3") {-word boundary-}
,IF_ARCH_sparc(ptext SLIT(".text\n\t.align 4") {-word boundary-}
,IF_ARCH_i386((text ".text\n\t.align 4,0x90") {-needs per-OS variation!-}
,)))
,IF_ARCH_powerpc(ptext SLIT(".text\n.align 2")
,))))
pprInstr (SEGMENT DataSegment)
= ptext
IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
,IF_ARCH_i386(SLIT(".data\n\t.align 4")
,)))
,IF_ARCH_powerpc(SLIT(".data\n.align 2")
,))))
pprInstr (SEGMENT RoDataSegment)
= ptext
IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
,)))
,IF_ARCH_powerpc(SLIT(".const_data\n.align 2")
,))))
pprInstr (LABEL clab)
= let
......@@ -435,7 +521,8 @@ pprInstr (LABEL clab)
IF_ARCH_alpha(SLIT("\t.globl\t")
,IF_ARCH_i386(SLIT(".globl ")
,IF_ARCH_sparc(SLIT(".global\t")
,)))
,IF_ARCH_powerpc(SLIT(".globl ")
,))))
, pp_lab, char '\n'],
pp_lab,
char ':'
......@@ -484,6 +571,19 @@ pprInstr (DATA s xs)
= let bs = doubleToBytes (fromRational r)
in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
#endif
#if powerpc_TARGET_ARCH
ppr_item B x = [ptext SLIT("\t.byte\t") <> pprImm x]
ppr_item Bu x = [ptext SLIT("\t.byte\t") <> pprImm x]
ppr_item H x = [ptext SLIT("\t.byte\t") <> pprImm x]
ppr_item Hu x = [ptext SLIT("\t.byte\t") <> pprImm x]
ppr_item W x = [ptext SLIT("\t.long\t") <> pprImm x]
ppr_item F (ImmFloat r)
= let bs = floatToBytes (fromRational r)
in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
ppr_item DF (ImmDouble r)
= let bs = doubleToBytes (fromRational r)
in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
#endif
-- fall through to rest of (machine-specific) pprInstr...
\end{code}
......@@ -1734,6 +1834,212 @@ pp_comma_a = text ",a"
#endif {-sparc_TARGET_ARCH-}
\end{code}
%************************************************************************
%* *
\subsubsection{@pprInstr@ for PowerPC}
%* *
%************************************************************************
\begin{code}
#if powerpc_TARGET_ARCH
pprInstr (LD sz reg addr) = hcat [
char '\t',
ptext SLIT("l"),