+ fun stackoper (X.TEMP temp, s) =
+ let
+ val base = (X.REG X.RSP, Tm.Quad)
+ val offs = (X.CONST (Word32.fromInt (stackpos (temptonum temp))), Tm.Quad)
+ in
+ if (isspilled (X.TEMP temp, s))
+ then (X.REL (base, offs, 0w1), s)
+ else raise ErrorMsg.InternalError "stackoper on unspilled temp?"
+ end
+ | stackoper (X.STACKARG arg, s) =
+ let
+ val base = (X.REG X.RSP, Tm.Quad)
+ val offs = (X.CONST (Word32.fromInt (stacksz + 8 + (arg * 8))), Tm.Quad)
+ in
+ (X.REL (base, offs, 0w1), s)
+ end
+ | stackoper (a as (X.REL _, s)) = a
+ | stackoper (a as (X.CONST _, s)) = a
+ | stackoper anous = raise ErrorMsg.InternalError ("stackoper on not temp " ^ X.pp_oper anous)
+
+ fun ophit (X.REL(op1, op2, m), s) =
+ if (isspilled op1 andalso isspilled op2) then
+ ([X.MOV ((X.REG spillreg1, Tm.Long), stackoper op2),
+ X.IMUL((X.REG spillreg1, Tm.Quad), (X.CONST m, Tm.Quad)),
+ X.ADD ((X.REG spillreg1, Tm.Quad), stackoper op1)],
+ (X.REL ((X.REG spillreg1, Tm.Quad), (X.CONST 0w0, Tm.Quad), 0w1), s))
+ else if(isspilled op1) then
+ ([X.MOV ((X.REG spillreg1, Tm.Quad), stackoper op1)],
+ (X.REL ((X.REG spillreg1, Tm.Quad), realoper op2, m), s))
+ else if(isspilled op2) then
+ ([X.MOV ((X.REG spillreg1, Tm.Long), stackoper op2)],
+ (X.REL (realoper op1, (X.REG spillreg1, Tm.Quad), m), s))
+ else
+ ([],
+ (X.REL (realoper op1, realoper op2, m), s))
+ | ophit a = (nil, realoper a handle Spilled => stackoper a)
+