| ... |
... |
@@ -180,7 +180,7 @@ stmtToInstrs stmt = do |
|
180
|
180
|
format = cmmTypeFormat ty
|
|
181
|
181
|
|
|
182
|
182
|
CmmUnsafeForeignCall target result_regs args
|
|
183
|
|
- -> genCCall target result_regs args
|
|
|
183
|
+ -> genCCall platform target result_regs args
|
|
184
|
184
|
|
|
185
|
185
|
CmmBranch id -> genBranch id
|
|
186
|
186
|
CmmCondBranch arg true false prediction -> do
|
| ... |
... |
@@ -338,6 +338,8 @@ iselExpr64 (CmmReg (CmmLocal local_reg)) = do |
|
338
|
338
|
let Reg64 hi lo = localReg64 local_reg
|
|
339
|
339
|
return (RegCode64 nilOL hi lo)
|
|
340
|
340
|
|
|
|
341
|
+iselExpr64 regoff@(CmmRegOff _ _) = iselExpr64 $ mangleIndexTree regoff
|
|
|
342
|
+
|
|
341
|
343
|
iselExpr64 (CmmLit (CmmInt i _)) = do
|
|
342
|
344
|
Reg64 rhi rlo <- getNewReg64
|
|
343
|
345
|
let
|
| ... |
... |
@@ -1183,24 +1185,25 @@ genCondJump id bool prediction = do |
|
1183
|
1185
|
-- @get_arg@, which moves the arguments to the correct registers/stack
|
|
1184
|
1186
|
-- locations. Apart from that, the code is easy.
|
|
1185
|
1187
|
|
|
1186
|
|
-genCCall :: ForeignTarget -- function to call
|
|
|
1188
|
+genCCall :: Platform
|
|
|
1189
|
+ -> ForeignTarget -- function to call
|
|
1187
|
1190
|
-> [CmmFormal] -- where to put the result
|
|
1188
|
1191
|
-> [CmmActual] -- arguments (of mixed type)
|
|
1189
|
1192
|
-> NatM InstrBlock
|
|
1190
|
|
-genCCall (PrimTarget MO_AcquireFence) _ _
|
|
|
1193
|
+genCCall _ (PrimTarget MO_AcquireFence) _ _
|
|
1191
|
1194
|
= return $ unitOL LWSYNC
|
|
1192
|
|
-genCCall (PrimTarget MO_ReleaseFence) _ _
|
|
|
1195
|
+genCCall _ (PrimTarget MO_ReleaseFence) _ _
|
|
1193
|
1196
|
= return $ unitOL LWSYNC
|
|
1194
|
|
-genCCall (PrimTarget MO_SeqCstFence) _ _
|
|
|
1197
|
+genCCall _ (PrimTarget MO_SeqCstFence) _ _
|
|
1195
|
1198
|
= return $ unitOL HWSYNC
|
|
1196
|
1199
|
|
|
1197
|
|
-genCCall (PrimTarget MO_Touch) _ _
|
|
|
1200
|
+genCCall _ (PrimTarget MO_Touch) _ _
|
|
1198
|
1201
|
= return $ nilOL
|
|
1199
|
1202
|
|
|
1200
|
|
-genCCall (PrimTarget (MO_Prefetch_Data _)) _ _
|
|
|
1203
|
+genCCall _ (PrimTarget (MO_Prefetch_Data _)) _ _
|
|
1201
|
1204
|
= return $ nilOL
|
|
1202
|
1205
|
|
|
1203
|
|
-genCCall (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n]
|
|
|
1206
|
+genCCall _ (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n]
|
|
1204
|
1207
|
= do let fmt = intFormat width
|
|
1205
|
1208
|
reg_dst = getLocalRegReg dst
|
|
1206
|
1209
|
(instr, n_code) <- case amop of
|
| ... |
... |
@@ -1250,7 +1253,7 @@ genCCall (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n] |
|
1250
|
1253
|
(n_reg, n_code) <- getSomeReg n
|
|
1251
|
1254
|
return (op dst dst (RIReg n_reg), n_code)
|
|
1252
|
1255
|
|
|
1253
|
|
-genCCall (PrimTarget (MO_AtomicRead width _)) [dst] [addr]
|
|
|
1256
|
+genCCall _ (PrimTarget (MO_AtomicRead width _)) [dst] [addr]
|
|
1254
|
1257
|
= do let fmt = intFormat width
|
|
1255
|
1258
|
reg_dst = getLocalRegReg dst
|
|
1256
|
1259
|
form = if widthInBits width == 64 then DS else D
|
| ... |
... |
@@ -1277,12 +1280,12 @@ genCCall (PrimTarget (MO_AtomicRead width _)) [dst] [addr] |
|
1277
|
1280
|
-- This is also what gcc does.
|
|
1278
|
1281
|
|
|
1279
|
1282
|
|
|
1280
|
|
-genCCall (PrimTarget (MO_AtomicWrite width _)) [] [addr, val] = do
|
|
|
1283
|
+genCCall _ (PrimTarget (MO_AtomicWrite width _)) [] [addr, val] = do
|
|
1281
|
1284
|
code <- assignMem_IntCode (intFormat width) addr val
|
|
1282
|
1285
|
return $ unitOL HWSYNC `appOL` code
|
|
1283
|
1286
|
|
|
1284
|
|
-genCCall (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new]
|
|
1285
|
|
- | width == W32 || width == W64
|
|
|
1287
|
+genCCall platform (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new]
|
|
|
1288
|
+ | width == W32 || (width == W64 && not (target32Bit platform))
|
|
1286
|
1289
|
= do
|
|
1287
|
1290
|
(old_reg, old_code) <- getSomeReg old
|
|
1288
|
1291
|
(new_reg, new_code) <- getSomeReg new
|
| ... |
... |
@@ -1311,9 +1314,8 @@ genCCall (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] |
|
1311
|
1314
|
format = intFormat width
|
|
1312
|
1315
|
|
|
1313
|
1316
|
|
|
1314
|
|
-genCCall (PrimTarget (MO_Clz width)) [dst] [src]
|
|
1315
|
|
- = do platform <- getPlatform
|
|
1316
|
|
- let reg_dst = getLocalRegReg dst
|
|
|
1317
|
+genCCall platform (PrimTarget (MO_Clz width)) [dst] [src]
|
|
|
1318
|
+ = do let reg_dst = getLocalRegReg dst
|
|
1317
|
1319
|
if target32Bit platform && width == W64
|
|
1318
|
1320
|
then do
|
|
1319
|
1321
|
RegCode64 code vr_hi vr_lo <- iselExpr64 src
|
| ... |
... |
@@ -1361,9 +1363,8 @@ genCCall (PrimTarget (MO_Clz width)) [dst] [src] |
|
1361
|
1363
|
let cntlz = unitOL (CNTLZ format reg_dst reg)
|
|
1362
|
1364
|
return $ s_code `appOL` pre `appOL` cntlz `appOL` post
|
|
1363
|
1365
|
|
|
1364
|
|
-genCCall (PrimTarget (MO_Ctz width)) [dst] [src]
|
|
1365
|
|
- = do platform <- getPlatform
|
|
1366
|
|
- let reg_dst = getLocalRegReg dst
|
|
|
1366
|
+genCCall platform (PrimTarget (MO_Ctz width)) [dst] [src]
|
|
|
1367
|
+ = do let reg_dst = getLocalRegReg dst
|
|
1367
|
1368
|
if target32Bit platform && width == W64
|
|
1368
|
1369
|
then do
|
|
1369
|
1370
|
let format = II32
|
| ... |
... |
@@ -1425,9 +1426,8 @@ genCCall (PrimTarget (MO_Ctz width)) [dst] [src] |
|
1425
|
1426
|
, SUBFC dst r' (RIImm (ImmInt (format_bits)))
|
|
1426
|
1427
|
]
|
|
1427
|
1428
|
|
|
1428
|
|
-genCCall target dest_regs argsAndHints
|
|
1429
|
|
- = do platform <- getPlatform
|
|
1430
|
|
- case target of
|
|
|
1429
|
+genCCall platform target dest_regs argsAndHints
|
|
|
1430
|
+ = do case target of
|
|
1431
|
1431
|
PrimTarget (MO_S_QuotRem width) -> divOp1 True width
|
|
1432
|
1432
|
dest_regs argsAndHints
|
|
1433
|
1433
|
PrimTarget (MO_U_QuotRem width) -> divOp1 False width
|