| ... |
... |
@@ -467,48 +467,26 @@ getRegister' _ platform (CmmLoad mem pk _) |
|
467
|
467
|
return (Any II64 code)
|
|
468
|
468
|
|
|
469
|
469
|
-- catch simple cases of zero- or sign-extended load
|
|
470
|
|
-getRegister' _ _ (CmmMachOp (MO_UU_Conv W8 W32) [CmmLoad mem _ _]) = do
|
|
471
|
|
- Amode addr addr_code <- getAmode D mem
|
|
472
|
|
- return (Any II32 (\dst -> addr_code `snocOL` LD II8 dst addr))
|
|
473
|
|
-
|
|
474
|
|
-getRegister' _ _ (CmmMachOp (MO_XX_Conv W8 W32) [CmmLoad mem _ _]) = do
|
|
475
|
|
- Amode addr addr_code <- getAmode D mem
|
|
476
|
|
- return (Any II32 (\dst -> addr_code `snocOL` LD II8 dst addr))
|
|
477
|
|
-
|
|
478
|
|
-getRegister' _ _ (CmmMachOp (MO_UU_Conv W8 W64) [CmmLoad mem _ _]) = do
|
|
479
|
|
- Amode addr addr_code <- getAmode D mem
|
|
480
|
|
- return (Any II64 (\dst -> addr_code `snocOL` LD II8 dst addr))
|
|
481
|
|
-
|
|
482
|
|
-getRegister' _ _ (CmmMachOp (MO_XX_Conv W8 W64) [CmmLoad mem _ _]) = do
|
|
483
|
|
- Amode addr addr_code <- getAmode D mem
|
|
484
|
|
- return (Any II64 (\dst -> addr_code `snocOL` LD II8 dst addr))
|
|
485
|
|
-
|
|
486
|
|
--- Note: there is no Load Byte Arithmetic instruction, so no signed case here
|
|
487
|
|
-
|
|
488
|
|
-getRegister' _ _ (CmmMachOp (MO_UU_Conv W16 W32) [CmmLoad mem _ _]) = do
|
|
489
|
|
- Amode addr addr_code <- getAmode D mem
|
|
490
|
|
- return (Any II32 (\dst -> addr_code `snocOL` LD II16 dst addr))
|
|
491
|
|
-
|
|
492
|
|
-getRegister' _ _ (CmmMachOp (MO_SS_Conv W16 W32) [CmmLoad mem _ _]) = do
|
|
493
|
|
- Amode addr addr_code <- getAmode D mem
|
|
494
|
|
- return (Any II32 (\dst -> addr_code `snocOL` LA II16 dst addr))
|
|
495
|
|
-
|
|
496
|
|
-getRegister' _ _ (CmmMachOp (MO_UU_Conv W16 W64) [CmmLoad mem _ _]) = do
|
|
497
|
|
- Amode addr addr_code <- getAmode D mem
|
|
498
|
|
- return (Any II64 (\dst -> addr_code `snocOL` LD II16 dst addr))
|
|
499
|
|
-
|
|
500
|
|
-getRegister' _ _ (CmmMachOp (MO_SS_Conv W16 W64) [CmmLoad mem _ _]) = do
|
|
501
|
|
- Amode addr addr_code <- getAmode D mem
|
|
502
|
|
- return (Any II64 (\dst -> addr_code `snocOL` LA II16 dst addr))
|
|
503
|
|
-
|
|
504
|
|
-getRegister' _ _ (CmmMachOp (MO_UU_Conv W32 W64) [CmmLoad mem _ _]) = do
|
|
505
|
|
- Amode addr addr_code <- getAmode D mem
|
|
506
|
|
- return (Any II64 (\dst -> addr_code `snocOL` LD II32 dst addr))
|
|
507
|
|
-
|
|
508
|
|
-getRegister' _ _ (CmmMachOp (MO_SS_Conv W32 W64) [CmmLoad mem _ _]) = do
|
|
509
|
|
- -- lwa is DS-form. See Note [Power instruction format]
|
|
510
|
|
- Amode addr addr_code <- getAmode DS mem
|
|
511
|
|
- return (Any II64 (\dst -> addr_code `snocOL` LA II32 dst addr))
|
|
|
470
|
+getRegister' _ _ (CmmMachOp (MO_UU_Conv src tgt) [CmmLoad mem pk _])
|
|
|
471
|
+ | src < tgt
|
|
|
472
|
+ , cmmTypeFormat pk == intFormat src = loadZeroExpand mem pk tgt
|
|
|
473
|
+
|
|
|
474
|
+getRegister' _ _ (CmmMachOp (MO_XX_Conv src tgt) [CmmLoad mem pk _])
|
|
|
475
|
+ | src < tgt
|
|
|
476
|
+ , cmmTypeFormat pk == intFormat src = loadZeroExpand mem pk tgt
|
|
|
477
|
+
|
|
|
478
|
+ -- XXX: This is ugly, refactor
|
|
|
479
|
+getRegister' _ _ (CmmMachOp (MO_SS_Conv src tgt) [CmmLoad mem pk _])
|
|
|
480
|
+ -- Note: there is no Load Byte Arithmetic instruction
|
|
|
481
|
+ | cmmTypeFormat pk /= II8
|
|
|
482
|
+ , src < tgt = do
|
|
|
483
|
+ let format = cmmTypeFormat pk
|
|
|
484
|
+ -- lwa is DS-form. See Note [Power instruction format]
|
|
|
485
|
+ let form = if format >= II32 then DS else D
|
|
|
486
|
+ Amode addr addr_code <- getAmode form mem
|
|
|
487
|
+ let code dst = assert (format == intFormat src)
|
|
|
488
|
+ $ addr_code `snocOL` LA format dst addr
|
|
|
489
|
+ return (Any (intFormat tgt) code)
|
|
512
|
490
|
|
|
513
|
491
|
getRegister' config platform (CmmMachOp (MO_RelaxedRead w) [e]) =
|
|
514
|
492
|
getRegister' config platform (CmmLoad e (cmmBits w) NaturallyAligned)
|
| ... |
... |
@@ -789,6 +767,12 @@ extendSExpr from to x = CmmMachOp (MO_SS_Conv from to) [x] |
|
789
|
767
|
extendUExpr :: Width -> Width -> CmmExpr -> CmmExpr
|
|
790
|
768
|
extendUExpr from to x = CmmMachOp (MO_UU_Conv from to) [x]
|
|
791
|
769
|
|
|
|
770
|
+loadZeroExpand :: CmmExpr -> CmmType -> Width -> NatM Register
|
|
|
771
|
+loadZeroExpand mem pk tgt = do
|
|
|
772
|
+ Amode addr addr_code <- getAmode D mem
|
|
|
773
|
+ let code dst = addr_code `snocOL` LD (cmmTypeFormat pk) dst addr
|
|
|
774
|
+ return (Any (intFormat tgt) code)
|
|
|
775
|
+
|
|
792
|
776
|
-- -----------------------------------------------------------------------------
|
|
793
|
777
|
-- The 'Amode' type: Memory addressing modes passed up the tree.
|
|
794
|
778
|
|
| ... |
... |
@@ -2448,8 +2432,8 @@ srCode width sgn instr x y = do |
|
2448
|
2432
|
let op_len = max W32 width
|
|
2449
|
2433
|
extend = if sgn then extendSExpr else extendUExpr
|
|
2450
|
2434
|
(src1, code1) <- getSomeReg (extend width op_len x)
|
|
2451
|
|
- (src2, code2) <- getSomeReg (extendUExpr width op_len y)
|
|
2452
|
|
- -- Note: Shift amount `y` is unsigned
|
|
|
2435
|
+ (src2, code2) <- getSomeReg y
|
|
|
2436
|
+
|
|
2453
|
2437
|
let code dst = code1 `appOL` code2 `snocOL`
|
|
2454
|
2438
|
instr (intFormat op_len) dst src1 (RIReg src2)
|
|
2455
|
2439
|
return (Any (intFormat width) code)
|