-condIntCode cond (StInd _ x) y
- = getAmode x `thenUs` \ amode ->
- getRegister y `thenUs` \ register2 ->
- getNewRegNCG IntRep `thenUs` \ tmp2 ->
- let
- code1 = amodeCode amode asmVoid
- src1 = amodeAddr amode
- code2 = registerCode register2 tmp2 asmVoid
- src2 = registerName register2 tmp2
- code__2 = asmParThen [code1, code2] .
- mkSeqInstr (CMP L (OpReg src2) (OpAddr src1))
- in
- returnUs (CondCode False cond code__2)
-
-condIntCode cond y (StInd _ x)
- = getAmode x `thenUs` \ amode ->
- getRegister y `thenUs` \ register2 ->
- getNewRegNCG IntRep `thenUs` \ tmp2 ->
- let
- code1 = amodeCode amode asmVoid
- src1 = amodeAddr amode
- code2 = registerCode register2 tmp2 asmVoid
- src2 = registerName register2 tmp2
- code__2 = asmParThen [code1, code2] .
- mkSeqInstr (CMP L (OpAddr src1) (OpReg src2))
- in
- returnUs (CondCode False cond code__2)
-
+-- memory vs anything
+condIntCode cond (StInd pk x) y
+ = getAmode x `thenNat` \ amode_x ->
+ getRegister y `thenNat` \ reg_y ->
+ getNewRegNCG IntRep `thenNat` \ tmp ->
+ let
+ c_x = amodeCode amode_x
+ am_x = amodeAddr amode_x
+ c_y = registerCode reg_y tmp
+ r_y = registerName reg_y tmp
+ sz = primRepToSize pk
+
+ -- optimisation: if there's no code for x, just an amode,
+ -- use whatever reg y winds up in. Assumes that c_y doesn't
+ -- clobber any regs in the amode am_x, which I'm not sure is
+ -- justified. The otherwise clause makes the same assumption.
+ code__2 | isNilOL c_x
+ = c_y `snocOL`
+ CMP sz (OpReg r_y) (OpAddr am_x)
+
+ | otherwise
+ = c_y `snocOL`
+ MOV L (OpReg r_y) (OpReg tmp) `appOL`
+ c_x `snocOL`
+ CMP sz (OpReg tmp) (OpAddr am_x)
+ in
+ returnNat (CondCode False cond code__2)
+
+-- anything vs memory
+--
+condIntCode cond y (StInd pk x)
+ = getAmode x `thenNat` \ amode_x ->
+ getRegister y `thenNat` \ reg_y ->
+ getNewRegNCG IntRep `thenNat` \ tmp ->
+ let
+ c_x = amodeCode amode_x
+ am_x = amodeAddr amode_x
+ c_y = registerCode reg_y tmp
+ r_y = registerName reg_y tmp
+ sz = primRepToSize pk
+ -- same optimisation and nagging doubts as previous clause
+ code__2 | isNilOL c_x
+ = c_y `snocOL`
+ CMP sz (OpAddr am_x) (OpReg r_y)
+
+ | otherwise
+ = c_y `snocOL`
+ MOV L (OpReg r_y) (OpReg tmp) `appOL`
+ c_x `snocOL`
+ CMP sz (OpAddr am_x) (OpReg tmp)
+ in
+ returnNat (CondCode False cond code__2)
+
+-- anything vs anything