Index: m3back/src/Codex86.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Codex86.i3,v retrieving revision 1.2 diff -u -r1.2 Codex86.i3 --- m3back/src/Codex86.i3 20 Jan 2010 12:56:21 -0000 1.2 +++ m3back/src/Codex86.i3 20 Jan 2010 14:53:37 -0000 @@ -9,12 +9,9 @@ INTERFACE Codex86; IMPORT M3CG, M3ObjFile, TFloat; - FROM M3CG IMPORT MType, Label, ByteOffset, Alignment; FROM M3CG_Ops IMPORT ErrorHandler, WarningHandler; - -IMPORT M3x86Rep, Wrx86; - +IMPORT M3x86Rep, Wrx86, Target; FROM M3x86Rep IMPORT Operand, NRegs, MVar, x86Var, x86Proc, Regno; TYPE T <: Public; @@ -48,7 +45,7 @@ fstack_swap (); fstack_discard (); f_loadlit (READONLY flarr: FloatBytes; type: MType); - immOp (op: Op; READONLY dest: Operand; imm: INTEGER); + immOp (op: Op; READONLY dest: Operand; READONLY imm: Target.Int); binOp (op: Op; READONLY dest, src: Operand); tableOp (op: Op; READONLY dest, index: Operand; scale: INTEGER; table: MVar); Index: m3back/src/Codex86.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Codex86.m3,v retrieving revision 1.6 diff -u -r1.6 Codex86.m3 --- m3back/src/Codex86.m3 20 Jan 2010 12:56:21 -0000 1.6 +++ m3back/src/Codex86.m3 20 Jan 2010 14:53:39 -0000 @@ -9,7 +9,7 @@ MODULE Codex86; IMPORT Fmt, TargetMap, M3x86Rep, M3ID, M3CG_Ops, Word, M3ObjFile, Wrx86, Target; -IMPORT TInt AS TargetInt; +IMPORT TInt; FROM TargetMap IMPORT CG_Bytes; @@ -22,6 +22,8 @@ FROM M3ObjFile IMPORT Seg; +CONST TZero = TInt.Zero; + REVEAL T = Public BRANDED "Codex86.T" OBJECT parent : M3x86Rep.U := NIL; obj : M3ObjFile.T := NIL; @@ -149,7 +151,7 @@ ins.opcode := 16_E8; ins.disp := rel; ins.dsize := 4; - Mn(t, "CALL PC +"); MnImm(t, rel); + Mn(t, "CALL PC +"); MnImmInt(t, rel); writecode(t, ins); END relCall; @@ -190,7 +192,7 @@ VAR ins: Instruction; BEGIN <* ASSERT psize < 16_8000 *> - Mn(t, "RET"); MnImm(t, psize); + Mn(t, "RET"); MnImmInt(t, psize); ins.opcode := 16_C2; ins.imm := psize; ins.imsize := 2; @@ -375,17 +377,19 @@ writecode(t, ins); END noargOp; -PROCEDURE immOp (t: T; op: Op; READONLY dest: Operand; imm: INTEGER) = +PROCEDURE immOp (t: T; op: Op; READONLY dest: Operand; READONLY imm: Target.Int) = VAR ins: Instruction; BEGIN <* ASSERT dest.loc = OLoc.register OR dest.loc = OLoc.mem *> - ins.imm := imm; - IF imm < 16_80 AND imm >= -16_80 + IF NOT TInt.ToInt(imm, ins.imm) THEN + t.Err("immOp: unable to convert immediate to INTEGER"); + END; + IF TInt.GE(imm, TInt.MinS8) AND TInt.LE(imm, TInt.MaxS8) THEN ins.imsize := 1; ELSE ins.imsize := 4; END; - Mn(t, opcode[op].name); MnOp(t, dest); MnImm(t, imm); + Mn(t, opcode[op].name); MnOp(t, dest); MnImmTInt(t, imm); IF dest.loc = OLoc.register AND dest.reg = EAX AND ins.imsize = 4 THEN @@ -483,8 +487,8 @@ INC(ins.sib, 5); Mn(t, opcode[op].name); MnOp(t, dest); MnMVar(t, table); - Mn(t, "::["); MnOp(t, index); Mn(t, " *"); MnImm (t, scale); - Mn(t, " +"); MnImm(t, ins.disp); Mn(t, " ]"); + Mn(t, "::["); MnOp(t, index); Mn(t, " *"); MnImmInt (t, scale); + Mn(t, " +"); MnImmInt(t, ins.disp); Mn(t, " ]"); ins.opcode := opcode[op].rrm+1; writecode(t, ins); @@ -552,10 +556,14 @@ PROCEDURE movOp (t: T; READONLY dest, src: Operand) = VAR ins: Instruction; mnemonic: TEXT := NIL; + imm: INTEGER; BEGIN <* ASSERT dest.loc = OLoc.register OR dest.loc = OLoc.mem *> IF src.loc = OLoc.imm THEN - movImm(t, dest, src.imm); + IF NOT TInt.ToInt(src.imm, imm) THEN + t.Err("movOp: unable to convert immediate to INTEGER"); + END; + movImm(t, dest, imm); RETURN; END; @@ -651,7 +659,7 @@ ins.opcode := 16_C6; get_op_size(dest.mvar.t, ins); build_modrm(t, dest, t.opcode[0], ins); - Mn(t, "MOV"); MnOp(t, dest); MnImm(t, imm); + Mn(t, "MOV"); MnOp(t, dest); MnImmInt(t, imm); ins.imm := imm; ins.imsize := CG_Bytes[dest.mvar.t]; writecode(t, ins); @@ -662,7 +670,7 @@ ins.opcode := 16_B8 + dest.reg; ins.imm := imm; ins.imsize := 4; - Mn(t, "MOV"); MnOp(t, dest); MnImm(t, imm); + Mn(t, "MOV"); MnOp(t, dest); MnImmInt(t, imm); writecode(t, ins); END; END movImm; @@ -674,7 +682,9 @@ CASE src.loc OF | OLoc.imm => ins.opcode := 16_68; - ins.imm := src.imm; + IF NOT TInt.ToInt(src.imm, ins.imm) THEN + t.Err("pushOp: unable to convert immediate to INTEGER"); + END; ins.imsize := 4; writecode(t, ins); | OLoc.register => @@ -773,7 +783,9 @@ IF src.loc = OLoc.imm THEN build_modrm(t, t.reg[dest.reg], dest, ins); ins.opcode := 16_69; - ins.imm := src.imm; + IF NOT TInt.ToInt(src.imm, ins.imm) THEN + t.Err("imulOp: unable to convert immediate to INTEGER"); + END; ins.imsize := 4; writecode(t, ins); ELSE @@ -788,13 +800,13 @@ END END imulOp; -PROCEDURE imulImm (t: T; READONLY dest, src: Operand; imm, imsize: INTEGER) = +PROCEDURE imulImm (t: T; READONLY dest, src: Operand; imm: INTEGER; imsize: INTEGER) = VAR ins: Instruction; BEGIN <* ASSERT dest.loc = OLoc.register *> <* ASSERT src.loc # OLoc.mem OR CG_Bytes[src.mvar.t] = 4 *> build_modrm(t, src, dest, ins); - Mn(t, "IMUL"); MnOp(t, dest); MnOp(t, src); MnImm(t, imm); + Mn(t, "IMUL"); MnOp(t, dest); MnOp(t, src); MnImmInt(t, imm); IF imsize = 1 THEN ins.opcode := 16_6B; ELSE ins.opcode := 16_69; @@ -853,7 +865,7 @@ set_label(t, diffsignlab); (* .diffsignlab *) noargOp(t, Op.oCDQ); (* CDQ *) idivOp(t, divisor); (* IDIV EAX, divisor *) - immOp(t, Op.oCMP, t.reg[EDX], 0); (* CMP EDX, #0 *) + immOp(t, Op.oCMP, t.reg[EDX], TZero); (* CMP EDX, #0 *) brOp(t, Cond.E, endlab); (* JE endlab *) decOp(t, t.reg[EAX]); (* DEC EAX *) set_label(t, endlab); (* .endlab *) @@ -878,7 +890,7 @@ set_label(t, diffsignlab); (* .diffsignlab *) noargOp(t, Op.oCDQ); (* CDQ *) idivOp(t, divisor); (* IDIV EAX, divisor *) - immOp(t, Op.oCMP, t.reg[EDX], 0); (* CMP EDX, #0 *) + immOp(t, Op.oCMP, t.reg[EDX], TZero); (* CMP EDX, #0 *) brOp(t, Cond.E, endlab); (* JE endlab *) binOp(t, Op.oADD, t.reg[EDX], divisor); (* ADD EDX, divisor *) set_label(t, endlab); (* .endlab *) @@ -1148,7 +1160,9 @@ ins.opcode := 16_88; IF val.loc = OLoc.imm THEN ins.opcode := 16_C6; - ins.imm := val.imm; + IF NOT TInt.ToInt(val.imm, ins.imm) THEN + t.Err("store_ind: unable to convert immediate to INTEGER"); + END; ins.imsize := CG_Bytes[type]; END; @@ -1567,7 +1581,7 @@ CASE op.loc OF OLoc.fstack => Mn (t, " FST"); | OLoc.register => Mn (t, " ", RegName[op.reg]); - | OLoc.imm => Mn (t, " $", Fmt.Int (op.imm)); + | OLoc.imm => Mn (t, " $", TInt.ToText (op.imm)); | OLoc.mem => MnMVar (t, op.mvar); END END @@ -1623,12 +1637,19 @@ END; END MnProc; -PROCEDURE MnImm(t: T; imm: INTEGER) = +PROCEDURE MnImmTInt(t: T; READONLY imm: Target.Int) = + BEGIN + IF t.debug THEN + Mn(t, " $", TInt.ToText (imm)); + END; + END MnImmTInt; + +PROCEDURE MnImmInt(t: T; imm: INTEGER) = BEGIN IF t.debug THEN Mn(t, " $", Fmt.Int (imm)); END; - END MnImm; + END MnImmInt; PROCEDURE Mn (t: T; mn1, mn2, mn3: TEXT := NIL) = BEGIN @@ -1949,7 +1970,7 @@ WHILE f_lit # NIL DO FOR i := 0 TO f_lit.size-1 DO - EVAL TargetInt.FromInt(f_lit.arr[i], Target.Integer.bytes, tint); + EVAL TInt.FromInt(f_lit.arr[i], Target.Integer.bytes, tint); t.parent.init_int(f_lit.loc + i, tint, Type.Word8); END; @@ -1957,7 +1978,7 @@ END; WHILE abscall # NIL DO - t.parent.init_int(abscall.loc, TargetInt.Zero, Type.Int32); + t.parent.init_int(abscall.loc, TZero, Type.Int32); t.obj.relocate(intvar.symbol, abscall.loc, abscall.sym); abscall := abscall.link; END; Index: m3back/src/M3x86.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/M3x86.m3,v retrieving revision 1.10 diff -u -r1.10 M3x86.m3 --- m3back/src/M3x86.m3 20 Jan 2010 12:56:21 -0000 1.10 +++ m3back/src/M3x86.m3 20 Jan 2010 14:53:39 -0000 @@ -8,7 +8,7 @@ MODULE M3x86 EXPORTS M3x86, M3x86Rep; IMPORT Wr, Text, Fmt, IntRefTbl, Word, Convert; -IMPORT M3CG, M3ID, M3CG_Ops, Target, TInt AS TargetInt, TFloat AS TargetFloat; +IMPORT M3CG, M3ID, M3CG_Ops, Target, TInt, TFloat, TWord; IMPORT M3ObjFile, TargetMap; FROM TargetMap IMPORT CG_Bytes; @@ -213,6 +213,7 @@ (*---------------------------------------------------------------------------*) CONST + TZero = TInt.Zero; CompareOpName = ARRAY CompareOp OF TEXT { " EQ", " NE", " GT", " GE", " LT", " LE" }; CompareOpCond = ARRAY CompareOp OF Cond { @@ -1092,7 +1093,7 @@ pad_init(u, o); - EVAL TargetInt.ToInt(value, int); + EVAL TInt.ToInt(value, int); u.obj.append(u.init_varstore.seg, int, CG_Bytes[t]); INC(u.init_count, CG_Bytes[t]); END init_int; @@ -1201,7 +1202,7 @@ u.wr.NL (); END; - size := TargetFloat.ToBytes(f, flarr); + size := TFloat.ToBytes(f, flarr); <* ASSERT size = 4 OR size = 8 *> @@ -1353,7 +1354,7 @@ u.cg.pushOp(u.cg.reg[Codex86.EBP]); u.cg.movOp(u.cg.reg[Codex86.EBP], u.cg.reg[Codex86.ESP]); - u.cg.immOp(Op.oSUB, u.cg.reg[Codex86.ESP], 16_FFFF); + u.cg.immOp(Op.oSUB, u.cg.reg[Codex86.ESP], TInt.FFFF); u.procframe_ptr := u.obj.cursor(Seg.Text) - 4; u.cg.pushOp(u.cg.reg[Codex86.EBX]); @@ -1480,7 +1481,7 @@ u.wr.NL (); END; - u.vstack.doimm (Op.oCMP, 0, FALSE); + u.vstack.doimm (Op.oCMP, TZero, FALSE); u.cg.brOp (Cond.NZ, l); END if_true; @@ -1494,7 +1495,7 @@ u.wr.NL (); END; - u.vstack.doimm (Op.oCMP, 0, FALSE); + u.vstack.doimm (Op.oCMP, TZero, FALSE); u.cg.brOp (Cond.Z, l); END if_false; @@ -1755,8 +1756,8 @@ u.wr.NL (); END; - IF NOT TargetInt.ToInt(i, int) THEN - u.Err("Failed to convert target integer in load_integer"); + IF NOT TInt.ToInt(i, int) THEN + u.Err("load_integer: failed to convert target integer"); END; u.vstack.unlock(); u.vstack.pushimm(int); @@ -1775,7 +1776,7 @@ END; u.vstack.pushnew(t, Force.any); - size := TargetFloat.ToBytes(f, flarr); + size := TFloat.ToBytes(f, flarr); IF size # CG_Bytes[t] THEN u.Err("Floating size mismatch in load_float"); END; @@ -2163,6 +2164,7 @@ PROCEDURE not (u: U; t: IType) = (* s0.t := Word.Not (s0.t) *) + VAR not: Target.Int; BEGIN IF u.debug THEN u.wr.Cmd ("not"); @@ -2172,7 +2174,8 @@ WITH stack0 = u.vstack.pos(0, "not") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - u.vstack.set_imm(stack0, Word.Not (u.vstack.op(stack0).imm)); + TWord.Not (u.vstack.op(stack0).imm, not); + u.vstack.set_imm(stack0, not); ELSE u.vstack.unlock(); u.vstack.find(stack0, Force.anytemp); @@ -2232,6 +2235,9 @@ PROCEDURE shift_left (u: U; t: IType) = (* s1.t := Word.Shift (s1.t, s0.t) ; pop *) + VAR shiftResult: Target.Int; + and: Target.Int; + shiftCount: INTEGER; BEGIN IF u.debug THEN u.wr.Cmd ("shift_left"); @@ -2244,18 +2250,22 @@ stack1 = u.vstack.pos(1, "shift_left") DO IF u.vstack.loc(stack0) = OLoc.imm THEN IF u.vstack.loc(stack1) = OLoc.imm THEN - u.vstack.set_imm(stack1, Word.Shift(u.vstack.op(stack1).imm, - u.vstack.op(stack0).imm)); + IF NOT TInt.ToInt(u.vstack.op(stack0).imm, shiftCount) THEN + u.Err("unable to convert shift count to host integer"); + END; + TWord.Shift(u.vstack.op(stack1).imm, shiftCount, shiftResult); + u.vstack.set_imm(stack1, shiftResult); ELSE - u.vstack.set_imm(stack0, Word.And(u.vstack.op(stack0).imm, 16_1F)); - IF (u.vstack.op(stack0).imm # 0) THEN + TWord.And(u.vstack.op(stack0).imm, TInt.ThirtyOne, and); + u.vstack.set_imm(stack0, and); + IF TInt.NE(u.vstack.op(stack0).imm, TZero) THEN u.vstack.find(stack1, Force.anytemp); u.cg.immOp(Op.oSAL, u.vstack.op(stack1), u.vstack.op(stack0).imm); u.vstack.newdest(u.vstack.op(stack1)); END END ELSE - IF ((u.vstack.loc(stack1) # OLoc.imm) OR (u.vstack.op(stack1).imm # 0)) THEN + IF (u.vstack.loc(stack1) # OLoc.imm) OR TInt.NE(u.vstack.op(stack1).imm, TZero) THEN u.vstack.find(stack0, Force.regset, RegSet {Codex86.ECX}); u.vstack.find(stack1, Force.anytemp); @@ -2274,6 +2284,9 @@ PROCEDURE shift_right (u: U; t: IType) = (* s1.t := Word.Shift (s1.t, -s0.t) ; pop *) + VAR shiftCount: INTEGER; + shift: Target.Int; + and: Target.Int; BEGIN IF u.debug THEN u.wr.Cmd ("shift_right"); @@ -2285,19 +2298,23 @@ WITH stack0 = u.vstack.pos(0, "shift_right"), stack1 = u.vstack.pos(1, "shift_right") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - IF u.vstack.loc(stack1) = OLoc.imm THEN - u.vstack.set_imm(stack1, Word.Shift(u.vstack.op(stack1).imm, - -u.vstack.op(stack0).imm)); + IF u.vstack.loc(stack1) = OLoc.imm THEN + IF NOT TInt.ToInt(u.vstack.op(stack0).imm, shiftCount) THEN + u.Err("unable to convert shift count to host integer"); + END; + TWord.Shift(u.vstack.op(stack1).imm, -shiftCount, shift); + u.vstack.set_imm(stack1, shift); ELSE - u.vstack.set_imm(stack0, Word.And(u.vstack.op(stack0).imm, 16_1F)); - IF (u.vstack.op(stack0).imm # 0) THEN + TWord.And(u.vstack.op(stack0).imm, TInt.ThirtyOne, and); + u.vstack.set_imm(stack0, and); + IF TInt.NE(u.vstack.op(stack0).imm, TZero) THEN u.vstack.find(stack1, Force.anytemp); u.cg.immOp(Op.oSHR, u.vstack.op(stack1), u.vstack.op(stack0).imm); u.vstack.newdest(u.vstack.op(stack1)); END END ELSE - IF ((u.vstack.loc(stack1) # OLoc.imm) OR (u.vstack.op(stack1).imm # 0)) THEN + IF ((u.vstack.loc(stack1) # OLoc.imm) OR (TInt.NE(u.vstack.op(stack1).imm, TZero))) THEN u.vstack.find(stack0, Force.regset, RegSet {Codex86.ECX}); u.vstack.find(stack1, Force.anytemp); @@ -2328,6 +2345,9 @@ PROCEDURE rotate_left (u: U; t: IType) = (* s1.t := Word.Rotate (s1.t, s0.t) ; pop *) + VAR rotateCount: INTEGER; + rotate: Target.Int; + and: Target.Int; BEGIN IF u.debug THEN u.wr.Cmd ("rotate_left"); @@ -2340,11 +2360,15 @@ stack1 = u.vstack.pos(1, "rotate_left") DO IF u.vstack.loc(stack0) = OLoc.imm THEN IF u.vstack.loc(stack1) = OLoc.imm THEN - u.vstack.set_imm(stack1, Word.Rotate(u.vstack.op(stack1).imm, - u.vstack.op(stack0).imm)); + IF NOT TInt.ToInt(u.vstack.op(stack0).imm, rotateCount) THEN + u.Err("unable to convert rotate count to host integer"); + END; + TWord.Rotate(u.vstack.op(stack1).imm, rotateCount, rotate); + u.vstack.set_imm(stack1, rotate); ELSE u.vstack.find(stack1, Force.anytemp); - u.vstack.set_imm(stack0, Word.And(u.vstack.op(stack0).imm, 16_1F)); + TWord.And(u.vstack.op(stack0).imm, TInt.ThirtyOne, and); + u.vstack.set_imm(stack0, and); u.cg.immOp(Op.oROL, u.vstack.op(stack1), u.vstack.op(stack0).imm); u.vstack.newdest(u.vstack.op(stack1)); END @@ -2366,6 +2390,9 @@ PROCEDURE rotate_right (u: U; t: IType) = (* s1.t := Word.Rotate (s1.t, -s0.t) ; pop *) + VAR rotateCount: INTEGER; + rotate: Target.Int; + and: Target.Int; BEGIN IF u.debug THEN u.wr.Cmd ("rotate_right"); @@ -2378,11 +2405,15 @@ stack1 = u.vstack.pos(1, "rotate_right") DO IF u.vstack.loc(stack0) = OLoc.imm THEN IF u.vstack.loc(stack1) = OLoc.imm THEN - u.vstack.set_imm(stack1, Word.Rotate(u.vstack.op(stack1).imm, - -u.vstack.op(stack0).imm)); + IF NOT TInt.ToInt(u.vstack.op(stack0).imm, rotateCount) THEN + u.Err("unable to convert rotate count to host integer"); + END; + TWord.Rotate(u.vstack.op(stack1).imm, -rotateCount, rotate); + u.vstack.set_imm(stack1, rotate); ELSE u.vstack.find(stack1, Force.anytemp); - u.vstack.set_imm(stack0, Word.And(u.vstack.op(stack0).imm, 16_1F)); + TWord.And(u.vstack.op(stack0).imm, TInt.ThirtyOne, and); + u.vstack.set_imm(stack0, and); u.cg.immOp(Op.oROR, u.vstack.op(stack1), u.vstack.op(stack0).imm); u.vstack.newdest(u.vstack.op(stack1)); END @@ -2545,7 +2576,8 @@ PROCEDURE copy_n (u: U; z: IType; t: MType; overlap: BOOLEAN) = (* Mem[s2.A:s0.z] := Mem[s1.A:s0.z]; pop(3)*) CONST Mover = ARRAY BOOLEAN OF Builtin { Builtin.memcpy, Builtin.memmove }; - VAR shift, n: INTEGER; mover := Mover [overlap]; + VAR n: INTEGER; mover := Mover [overlap]; + shift: Target.Int; BEGIN IF u.debug THEN u.wr.Cmd ("copy_n"); @@ -2557,7 +2589,9 @@ WITH stack0 = u.vstack.pos(0, "copy_n") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - n := u.vstack.op(stack0).imm; + IF NOT TInt.ToInt(u.vstack.op(stack0).imm, n) THEN + u.Err("copy_n: unable to convert to host integer"); + END; u.vstack.discard(1); copy(u, n, t, overlap); RETURN; @@ -2569,9 +2603,9 @@ u.vstack.unlock(); CASE CG_Bytes[t] OF - 2 => shift := 1; - | 4 => shift := 2; - | 8 => shift := 3; + 2 => shift := TInt.One; + | 4 => shift := TInt.Two; + | 8 => shift := TInt.Three; ELSE u.Err("Unknown MType size in copy_n"); END; @@ -2618,6 +2652,7 @@ END inline_copy; PROCEDURE string_copy (u: U; n, size: INTEGER; forward: BOOLEAN) = + VAR tn, tNMinus1, tsize, t: Target.Int; BEGIN u.vstack.corrupt(Codex86.ECX); u.cg.movImm(u.cg.reg[Codex86.ECX], n); @@ -2625,8 +2660,21 @@ IF forward THEN u.cg.noargOp(Op.oCLD); ELSE - u.cg.immOp(Op.oADD, u.cg.reg[Codex86.ESI], (n - 1) * size); - u.cg.immOp(Op.oADD, u.cg.reg[Codex86.EDI], (n - 1) * size); + IF NOT TInt.FromInt(n, Target.Integer.bytes, tn) THEN + u.Err("string_copy: unable to convert n to target int"); + END; + IF NOT TInt.FromInt(size, Target.Integer.bytes, tsize) THEN + u.Err("string_copy: unable to convert size to target int"); + END; + IF NOT TInt.Subtract(tn, TInt.One, tNMinus1) THEN + u.Err("string_copy: Subtract overflowed"); + END; + (* Beware TWord.Multiply: x * 1 = 0 *) + IF NOT TInt.Multiply(tNMinus1, tsize, t) THEN + u.Err("string_copy: Multiply overflowed"); + END; + u.cg.immOp(Op.oADD, u.cg.reg[Codex86.ESI], t); + u.cg.immOp(Op.oADD, u.cg.reg[Codex86.EDI], t); u.cg.noargOp(Op.oSTD); END; @@ -2720,7 +2768,8 @@ PROCEDURE zero_n (u: U; z: IType; t: MType) = (* Mem[s1.A:s0.z] := 0; pop(2) *) - VAR shift, n: INTEGER; + VAR n: INTEGER; + shift: Target.Int; BEGIN IF u.debug THEN u.wr.Cmd ("zero_n"); @@ -2731,7 +2780,9 @@ WITH stack0 = u.vstack.pos(0, "zero_n") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - n := u.vstack.op(stack0).imm; + IF NOT TInt.ToInt(u.vstack.op(stack0).imm, n) THEN + u.Err("zero_n: unable to convert to host integer"); + END; u.vstack.discard(1); zero(u, n, t); RETURN; @@ -2744,9 +2795,9 @@ u.vstack.find(stack0, Force.anyreg); CASE CG_Bytes[t] OF - 2 => shift := 1; - | 4 => shift := 2; - | 8 => shift := 3; + 2 => shift := TInt.One; + | 4 => shift := TInt.Two; + | 8 => shift := TInt.Three; ELSE u.Err("Unknown MType size in zero_n"); END; @@ -2817,7 +2868,7 @@ WITH stack0 = u.vstack.pos(0, "zero"), stop0 = u.vstack.op(stack0) DO u.vstack.find(stack0, Force.anyreg, RegSet {}, TRUE); FOR i := 0 TO n - 1 DO - u.cg.store_ind(Operand { loc := OLoc.imm, imm := 0 }, + u.cg.store_ind(Operand { loc := OLoc.imm, imm := TZero }, stop0, i * size, faketype[size]); END END @@ -2931,14 +2982,14 @@ u.vstack.unlock(); WITH stack0 = u.vstack.pos(0, "check_nil") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - IF u.vstack.op(stack0).imm = 0 THEN + IF TInt.EQ(u.vstack.op(stack0).imm, TZero) THEN reportfault(u, code); END ELSE u.vstack.find(stack0, Force.anyreg, RegSet {}, TRUE); IF NOT u.vstack.non_nil(u.vstack.reg(stack0)) THEN - u.cg.immOp(Op.oCMP, u.vstack.op(stack0), 0); + u.cg.immOp(Op.oCMP, u.vstack.op(stack0), TZero); safelab := u.cg.reserve_labels(1, TRUE); u.cg.brOp(Cond.NE, safelab); reportfault(u, code); @@ -2952,7 +3003,7 @@ PROCEDURE check_lo (u: U; t: IType; READONLY i: Target.Int; code: RuntimeError) = (* IF (s0.t < i) THEN abort(code) *) - VAR int: INTEGER; safelab: Label; + VAR safelab: Label; BEGIN IF u.debug THEN u.wr.Cmd ("check_lo"); @@ -2962,27 +3013,25 @@ u.wr.NL (); END; - EVAL TargetInt.ToInt(i, int); - u.vstack.unlock(); WITH stack0 = u.vstack.pos(0, "check_lo") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - IF u.vstack.op(stack0).imm < int THEN + IF TInt.LT(u.vstack.op(stack0).imm, i) THEN reportfault(u, code); END ELSE u.vstack.find(stack0, Force.anyreg); - IF u.vstack.lower(u.vstack.reg(stack0)) >= int THEN + IF TInt.GE(u.vstack.lower(u.vstack.reg(stack0)), i) THEN (* ok *) - ELSIF u.vstack.upper(u.vstack.reg(stack0)) < int THEN + ELSIF TInt.LT(u.vstack.upper(u.vstack.reg(stack0)), i) THEN reportfault(u, code); ELSE - u.cg.immOp(Op.oCMP, u.vstack.op(stack0), int); + u.cg.immOp(Op.oCMP, u.vstack.op(stack0), i); safelab := u.cg.reserve_labels(1, TRUE); u.cg.brOp(Cond.GE, safelab); reportfault(u, code); u.cg.set_label(safelab); - u.vstack.set_lower(u.vstack.reg(stack0), int); + u.vstack.set_lower(u.vstack.reg(stack0), i); END END END @@ -2990,8 +3039,7 @@ PROCEDURE check_hi (u: U; t: IType; READONLY i: Target.Int; code: RuntimeError) = (* IF (i < s0.t) THEN abort(code) *) - VAR int: INTEGER; - safelab: Label; + VAR safelab: Label; BEGIN IF u.debug THEN u.wr.Cmd ("check_hi"); @@ -3001,27 +3049,25 @@ u.wr.NL (); END; - EVAL TargetInt.ToInt(i, int); - u.vstack.unlock(); WITH stack0 = u.vstack.pos(0, "check_hi") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - IF int < u.vstack.op(stack0).imm THEN + IF TInt.LT(i, u.vstack.op(stack0).imm) THEN reportfault(u, code); END ELSE u.vstack.find(stack0, Force.anyreg); - IF u.vstack.upper(u.vstack.reg(stack0)) <= int THEN + IF TInt.LE(u.vstack.upper(u.vstack.reg(stack0)), i) THEN (* ok *) - ELSIF u.vstack.lower(u.vstack.reg(stack0)) > int THEN + ELSIF TInt.GT(u.vstack.lower(u.vstack.reg(stack0)), i) THEN reportfault(u, code); ELSE - u.cg.immOp(Op.oCMP, u.vstack.op(stack0), int); + u.cg.immOp(Op.oCMP, u.vstack.op(stack0), i); safelab := u.cg.reserve_labels(1, TRUE); u.cg.brOp(Cond.LE, safelab); reportfault(u, code); u.cg.set_label(safelab); - u.vstack.set_upper(u.vstack.reg(stack0), int); + u.vstack.set_upper(u.vstack.reg(stack0), i); END END END @@ -3029,7 +3075,7 @@ PROCEDURE check_range (u: U; t: IType; READONLY a, b: Target.Int; code: RuntimeError) = (* IF (s0.t < a) OR (b < s0.t) THEN abort(code) *) - VAR inta, intb, lo, hi: INTEGER; safelab, outrange: Label; + VAR lo, hi: Target.Int; safelab, outrange: Label; BEGIN IF u.debug THEN u.wr.Cmd ("check_range"); @@ -3039,14 +3085,11 @@ u.wr.NL (); END; - EVAL TargetInt.ToInt(a, inta); - EVAL TargetInt.ToInt(b, intb); - u.vstack.unlock(); WITH stack0 = u.vstack.pos(0, "check_range") DO IF u.vstack.loc(stack0) = OLoc.imm THEN lo := u.vstack.op(stack0).imm; - IF (lo < inta) OR (intb < lo) THEN + IF TInt.LT(lo, a) OR TInt.LT(b, lo) THEN reportfault(u, code); END; RETURN; @@ -3056,35 +3099,35 @@ WITH reg = u.vstack.reg(stack0) DO lo := u.vstack.lower(reg); hi := u.vstack.upper(reg); - IF (inta <= lo) AND (hi <= intb) THEN + IF TInt.LE(a, lo) AND TInt.LE(hi, b) THEN (* ok *) - ELSIF (hi < inta) OR (intb < lo) THEN + ELSIF TInt.LT(hi, a) OR TInt.LT(b, lo) THEN reportfault(u, code); - ELSIF (hi <= intb) THEN + ELSIF TInt.LE(hi, b) THEN check_lo(u, t, a, code); - ELSIF (lo >= inta) THEN + ELSIF TInt.GE(lo, a) THEN check_hi(u, t, b, code); - ELSIF (inta = 0) THEN + ELSIF TInt.EQ(a, TZero) THEN (* 0 <= x <= b ==> UNSIGNED(x) <= b *) safelab := u.cg.reserve_labels(1, TRUE); - u.cg.immOp(Op.oCMP, u.vstack.op(stack0), intb); + u.cg.immOp(Op.oCMP, u.vstack.op(stack0), b); u.cg.brOp(unscond [Cond.LE], safelab); reportfault(u, code); u.cg.set_label(safelab); - u.vstack.set_upper(reg, intb); - u.vstack.set_lower(reg, inta); + u.vstack.set_upper(reg, b); + u.vstack.set_lower(reg, a); ELSE safelab := u.cg.reserve_labels(1, TRUE); outrange := u.cg.reserve_labels(1, TRUE); - u.cg.immOp(Op.oCMP, u.vstack.op(stack0), inta); + u.cg.immOp(Op.oCMP, u.vstack.op(stack0), a); u.cg.brOp(Cond.L, outrange); - u.cg.immOp(Op.oCMP, u.vstack.op(stack0), intb); + u.cg.immOp(Op.oCMP, u.vstack.op(stack0), b); u.cg.brOp(Cond.LE, safelab); u.cg.set_label(outrange); reportfault(u, code); u.cg.set_label(safelab); - u.vstack.set_upper(reg, intb); - u.vstack.set_lower(reg, inta); + u.vstack.set_upper(reg, b); + u.vstack.set_lower(reg, a); END; END END @@ -3109,7 +3152,7 @@ stack1 = u.vstack.pos(1, "check_index") DO IF u.vstack.loc(stack0) = OLoc.imm AND u.vstack.loc(stack1) = OLoc.imm THEN - IF Word.LE(u.vstack.op(stack0).imm, u.vstack.op(stack1).imm) THEN + IF TWord.LE(u.vstack.op(stack0).imm, u.vstack.op(stack1).imm) THEN reportfault(u, code); END ELSE @@ -3228,6 +3271,7 @@ PROCEDURE add_offset (u: U; i: INTEGER) = (* s0.A := s0.A + i *) + VAR ti, imm_plus_i: Target.Int; BEGIN IF u.debug THEN u.wr.Cmd ("add_offset"); @@ -3235,14 +3279,21 @@ u.wr.NL (); END; + IF NOT TInt.FromInt(i, Target.Integer.bytes, ti) THEN + u.Err("add_offset: failed to convert i to target integer"); + END; + u.vstack.unlock(); WITH stack0 = u.vstack.pos(0, "add_offset") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - u.vstack.set_imm(stack0, u.vstack.op(stack0).imm + i); + IF NOT TInt.Add(u.vstack.op(stack0).imm, ti, imm_plus_i) THEN + u.Err("add_offset: Add overflowed"); + END; + u.vstack.set_imm(stack0, imm_plus_i); ELSE u.vstack.find(stack0, Force.anytemp, RegSet {}, TRUE); - u.cg.immOp(Op.oADD, u.vstack.op(stack0), i); + u.cg.immOp(Op.oADD, u.vstack.op(stack0), ti); u.vstack.newdest(u.vstack.op(stack0)); END @@ -3348,9 +3399,9 @@ WITH stack0 = u.vstack.pos(0, "pop_param") DO IF Target.FloatType [t] THEN IF t = Type.Reel THEN - u.cg.immOp(Op.oSUB, u.cg.reg[Codex86.ESP], 4); + u.cg.immOp(Op.oSUB, u.cg.reg[Codex86.ESP], TInt.Four); ELSE - u.cg.immOp(Op.oSUB, u.cg.reg[Codex86.ESP], 8); + u.cg.immOp(Op.oSUB, u.cg.reg[Codex86.ESP], TInt.Eight); END; u.cg.f_storeind(u.cg.reg[Codex86.ESP], 0, t); @@ -3389,6 +3440,7 @@ PROCEDURE pop_struct (u: U; s: ByteSize; a: Alignment) = (* pop s0 and make it the "next" parameter in the current call *) + VAR ts: Target.Int; BEGIN IF u.debug THEN u.wr.Cmd ("pop_struct"); @@ -3407,8 +3459,12 @@ WITH stack0 = u.vstack.pos(0, "pop_struct") DO - IF s > 32 THEN - u.cg.immOp(Op.oSUB, u.cg.reg[Codex86.ESP], s); + IF NOT TInt.FromInt(s, Target.Integer.bytes, ts) THEN + u.Err("pop_struct: unable to convert s to target int"); + END; + + IF TInt.GT(ts, TInt.ThirtyTwo) THEN + u.cg.immOp(Op.oSUB, u.cg.reg[Codex86.ESP], ts); u.vstack.find(stack0, Force.regset, RegSet { Codex86.ESI }); u.vstack.corrupt(Codex86.EDI); @@ -3456,6 +3512,7 @@ PROCEDURE call_direct (u: U; p: Proc; t: Type) = VAR realproc := NARROW(p, x86Proc); + call_param_size: Target.Int; (* call the procedure identified by block b. The procedure returns a value of type t. *) BEGIN @@ -3488,8 +3545,11 @@ IF (NOT realproc.stdcall) (* => caller cleans *) AND u.call_param_size[u.in_proc_call-1] > 0 THEN - u.cg.immOp(Op.oADD, u.cg.reg[Codex86.ESP], - u.call_param_size[u.in_proc_call-1]); + + IF NOT TInt.FromInt(u.call_param_size[u.in_proc_call-1], Target.Integer.bytes, call_param_size) THEN + u.Err("call_direct: unable to convert param_size to target integer"); + END; + u.cg.immOp(Op.oADD, u.cg.reg[Codex86.ESP], call_param_size); END; IF t = Type.Struct THEN @@ -3512,6 +3572,7 @@ PROCEDURE call_indirect (u: U; t: Type; cc: CallingConvention) = (* call the procedure whose address is in s0.A and pop s0. The procedure returns a value of type t. *) + VAR call_param_size: Target.Int; BEGIN IF u.debug THEN u.wr.Cmd ("call_indirect"); @@ -3540,9 +3601,14 @@ IF (cc.m3cg_id = 0) AND u.call_param_size[u.in_proc_call-1] > 0 THEN + (* caller-cleans calling convention *) - u.cg.immOp(Op.oADD, u.cg.reg[Codex86.ESP], - u.call_param_size[u.in_proc_call-1]); + + IF NOT TInt.FromInt(u.call_param_size[u.in_proc_call-1], Target.Integer.bytes, call_param_size) THEN + u.Err("call_indirect: unable to convert param_size to target integer"); + END; + + u.cg.immOp(Op.oADD, u.cg.reg[Codex86.ESP], call_param_size); END; IF t = Type.Struct THEN @@ -3587,11 +3653,11 @@ <*ASSERT FALSE*> | Type.Word8 => (* 8-bit unsigned integer *) - u.cg.immOp (Op.oAND, u.cg.reg[Codex86.EAX], 16_ff); (* EAX &= 16_ff *) + u.cg.immOp (Op.oAND, u.cg.reg[Codex86.EAX], TInt.FF); (* EAX &= 16_FF *) t := Type.Word32; | Type.Word16 => (* 16-bit unsigned integer *) - u.cg.immOp (Op.oAND, u.cg.reg[Codex86.EAX], 16_ffff); (* EAX &= 16_ffff *) + u.cg.immOp (Op.oAND, u.cg.reg[Codex86.EAX], TInt.FFFF); (* EAX &= 16_FFFF *) t := Type.Word32; | Type.Word32 => (* 32-bit unsigned Integer *) @@ -3669,7 +3735,7 @@ PROCEDURE intregcmp (u: U; tozero: BOOLEAN): BOOLEAN = BEGIN IF tozero THEN - u.vstack.doimm(Op.oCMP, 0, FALSE); + u.vstack.doimm(Op.oCMP, TZero, FALSE); RETURN FALSE; ELSE RETURN u.vstack.dobin(Op.oCMP, TRUE, FALSE); Index: m3back/src/M3x86Rep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/M3x86Rep.i3,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 M3x86Rep.i3 --- m3back/src/M3x86Rep.i3 14 Jan 2001 13:40:21 -0000 1.1.1.1 +++ m3back/src/M3x86Rep.i3 20 Jan 2010 14:53:39 -0000 @@ -8,7 +8,7 @@ INTERFACE M3x86Rep; -IMPORT M3CG, M3ID; +IMPORT M3CG, M3ID, Target, TInt; FROM M3CG IMPORT ByteOffset, ByteSize, Alignment; FROM M3CG IMPORT Var, Proc, Name; @@ -89,7 +89,7 @@ loc: OLoc; mvar: MVar := NoStore; reg: Regno := 0; - imm: INTEGER := 0; + imm: Target.Int := TInt.Zero; stackp: INTEGER := 0; opcode := FALSE; END; Index: m3back/src/Stackx86.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Stackx86.i3,v retrieving revision 1.2 diff -u -r1.2 Stackx86.i3 --- m3back/src/Stackx86.i3 20 Jan 2010 12:56:21 -0000 1.2 +++ m3back/src/Stackx86.i3 20 Jan 2010 14:53:39 -0000 @@ -11,7 +11,7 @@ FROM M3CG IMPORT MType, ZType, Sign, ByteOffset; FROM M3CG_Ops IMPORT ErrorHandler, WarningHandler; -IMPORT M3x86Rep, Codex86, Wrx86; +IMPORT M3x86Rep, Codex86, Wrx86, Target; FROM M3x86Rep IMPORT Operand, OLoc, MVar, Regno, Force, RegSet, FlToInt; FROM M3x86Rep IMPORT x86Proc, x86Var; @@ -32,13 +32,13 @@ corrupt (reg: Regno); set_fstack (stackp: INTEGER); set_mvar (stackp: INTEGER; READONLY mvar: MVar); - set_imm (stackp, imm: INTEGER); + set_imm (stackp: INTEGER; READONLY imm: Target.Int); loc (stackp: INTEGER): OLoc; op (stackp: INTEGER): Operand; pos (depth: INTEGER; place: TEXT): INTEGER; discard (depth: INTEGER); set_error_handler (err: ErrorHandler); - set_warning_handler (err: WarningHandler); + set_warning_handler (warn: WarningHandler); push (READONLY mvar: MVar); pushnew (type: MType; force: Force; set := RegSet {}); pushimm (imm: INTEGER); @@ -68,16 +68,16 @@ doindex_address (shift, size: INTEGER; neg: BOOLEAN); docopy (type: MType; overlap: BOOLEAN); docopy_n (n: INTEGER; type: MType; overlap: BOOLEAN); - doimm (op: Op; imm: INTEGER; overwritesdest: BOOLEAN); + doimm (op: Op; READONLY imm: Target.Int; overwritesdest: BOOLEAN); newdest (READONLY op: Operand); init (); end (); set_current_proc (p: x86Proc); reg (stackp: INTEGER): Regno; - lower (reg: Regno): INTEGER; - set_lower (reg: Regno; low: INTEGER); - upper (reg: Regno): INTEGER; - set_upper (reg: Regno; up: INTEGER); + lower (reg: Regno): Target.Int; + set_lower (reg: Regno; low: Target.Int); + upper (reg: Regno): Target.Int; + set_upper (reg: Regno; up: Target.Int); non_nil (reg: Regno): BOOLEAN; set_non_nil (reg: Regno); END; Index: m3back/src/Stackx86.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Stackx86.m3,v retrieving revision 1.4 diff -u -r1.4 Stackx86.m3 --- m3back/src/Stackx86.m3 20 Jan 2010 12:56:21 -0000 1.4 +++ m3back/src/Stackx86.m3 20 Jan 2010 14:54:08 -0000 @@ -9,6 +9,7 @@ IMPORT M3ID, M3CG, TargetMap, M3CG_Ops, Word, M3x86Rep, Codex86, Wrx86; +IMPORT Target, TInt, TWord; FROM Target IMPORT FloatType; FROM TargetMap IMPORT CG_Bytes, CG_Align_bytes; @@ -20,6 +21,8 @@ FROM Codex86 IMPORT Op, FOp, Cond, revcond; +CONST TZero = TInt.Zero; + REVEAL T = Public BRANDED "Stackx86.T" OBJECT cg : Codex86.T := NIL; parent : M3x86Rep.U := NIL; @@ -31,7 +34,7 @@ vstacklimit := 0; reguse : ARRAY [0 .. NRegs] OF Register; current_proc : x86Proc; - rmode : ARRAY FlToInt OF INTEGER; + rmode : ARRAY FlToInt OF Target.Int; lowset_table : x86Var; highset_table : x86Var; OVERRIDES @@ -98,14 +101,19 @@ Register = RECORD stackp : INTEGER := -1; last_store : MVar := NoStore; - last_imm : INTEGER := 0; - lowbound : INTEGER := FIRST (INTEGER); - upbound : INTEGER := LAST (INTEGER); + last_imm : Target.Int := TZero; + lowbound : Target.Int := TInt.MinS32; + upbound : Target.Int := TInt.MaxS32; imm : BOOLEAN := FALSE; locked : BOOLEAN := FALSE; non_nil : BOOLEAN := FALSE; END; +PROCEDURE InitRegister():Register = +BEGIN + RETURN Register { lowbound := Target.Integer.min, upbound := Target.Integer.max }; +END InitRegister; + (*-------------------------------------------- register handling routines ---*) CONST HighPrec: INTEGER = NRegs * 1000; @@ -147,8 +155,8 @@ BEGIN t.cg.movOp(t.cg.reg[r], op); - t.reguse[r] := Register { locked := t.reguse[r].locked }; - + t.reguse[r] := InitRegister(); + t.reguse[r].locked := t.reguse[r].locked; t.reguse[r].stackp := op.stackp; IF op.loc = OLoc.mem THEN @@ -215,7 +223,7 @@ FOR r := 0 TO NRegs DO <* ASSERT t.reguse[r].stackp = -1 *> - t.reguse[r] := Register {}; + t.reguse[r] := InitRegister(); END END clearall; @@ -224,7 +232,7 @@ t.cg.wrFlush(); FOR r := 0 TO NRegs DO - t.reguse[r] := Register {}; + t.reguse[r] := InitRegister(); END END releaseall; @@ -234,6 +242,7 @@ hintaddr := FALSE) = (* Find a suitable register to put a stack item in *) VAR in, to: Regno; + imm: INTEGER; BEGIN CASE t.vstack[stackp].loc OF OLoc.fstack => @@ -258,7 +267,10 @@ (* If it is an immediate value and should be in mem, do it *) IF force = Force.mem AND t.vstack[stackp].loc = OLoc.imm THEN - get_temp(t, stackp, -1, t.vstack[stackp].imm); + IF NOT TInt.ToInt(t.vstack[stackp].imm, imm) THEN + t.Err("find: unable to convert target integer to host integer"); + END; + get_temp(t, stackp, -1, imm); RETURN; END; @@ -447,14 +459,14 @@ RETURN bestreg; END inreg; -PROCEDURE immreg (t: T; imm: INTEGER; set: RegSet:= RegSet {}): Regno = +PROCEDURE immreg (t: T; READONLY imm: Target.Int; set: RegSet:= RegSet {}): Regno = VAR minprec := HighPrec * HighPrec; prec := 0; bestreg: Regno := -1; BEGIN FOR i := 0 TO NRegs DO IF t.reguse[i].imm AND - imm = t.reguse[i].last_imm THEN + TInt.EQ(imm, t.reguse[i].last_imm) THEN prec := precedence(t, i); IF (set # RegSet {}) AND (NOT i IN set) THEN prec := prec * HighPrec; @@ -553,7 +565,8 @@ IF t.reguse[reg].stackp # -1 THEN forceout(t, reg); END; - t.reguse[reg] := Register { locked := t.reguse[reg].locked }; + t.reguse[reg] := InitRegister(); + t.reguse[reg].locked := t.reguse[reg].locked; END corrupt; PROCEDURE set_fstack (t: T; stackp: INTEGER) = @@ -567,7 +580,7 @@ t.vstack[stackp].mvar := mvar; END set_mvar; -PROCEDURE set_imm (t: T; stackp, imm: INTEGER) = +PROCEDURE set_imm (t: T; stackp: INTEGER; READONLY imm: Target.Int) = BEGIN t.vstack[stackp].loc := OLoc.imm; t.vstack[stackp].imm := imm; @@ -603,7 +616,10 @@ WITH stack0 = t.vstack[t.stacktop] DO stack0.loc := OLoc.imm; - stack0.imm := imm; + IF NOT TInt.FromInt(imm, Target.Integer.bytes, stack0.imm) THEN + t.Err("pushimm: unable to convert to target integer"); + END; + <* ASSERT TInt.EQ(stack0.imm, TZero) = (imm = 0) *> stack0.stackp := t.stacktop; END; @@ -754,6 +770,7 @@ END pop; PROCEDURE doloadaddress (t: T; v: x86Var; o: ByteOffset) = + VAR to, tvoffset, ti: Target.Int; BEGIN unlock(t); pushnew(t, Type.Addr, Force.anyreg); @@ -761,7 +778,16 @@ WITH stop0 = t.vstack[pos(t, 0, "doloadaddress")] DO IF v.loc = VLoc.temp AND v.parent # t.current_proc THEN t.cg.get_frame(stop0.reg, v.parent, t.current_proc); - t.cg.immOp(Op.oADD, t.cg.reg[stop0.reg], o + v.offset); + IF NOT TInt.FromInt(o, Target.Integer.bytes, to) THEN + t.Err("doloadaddress: unable to convert o"); + END; + IF NOT TInt.FromInt(v.offset, Target.Integer.bytes, tvoffset) THEN + t.Err("doloadaddress: unable to convert v.offset"); + END; + IF NOT TInt.Add(to, tvoffset, ti) THEN + t.Err("dloadaddress: Add overflowed"); + END; + t.cg.immOp(Op.oADD, t.cg.reg[stop0.reg], ti); ELSE t.cg.binOp(Op.oLEA, stop0, Operand {loc := OLoc.mem, @@ -973,7 +999,7 @@ IF (a = Sign.Positive AND b = Sign.Negative) OR (a = Sign.Negative AND b = Sign.Positive) THEN - t.cg.immOp(Op.oCMP, t.cg.reg[Codex86.EDX], 0); + t.cg.immOp(Op.oCMP, t.cg.reg[Codex86.EDX], TZero); neglabel := t.cg.reserve_labels(1, TRUE); @@ -1027,7 +1053,7 @@ IF (a = Sign.Positive AND b = Sign.Negative) OR (a = Sign.Negative AND b = Sign.Positive) THEN - t.cg.immOp(Op.oCMP, t.cg.reg[Codex86.EDX], 0); + t.cg.immOp(Op.oCMP, t.cg.reg[Codex86.EDX], TZero); neglabel := t.cg.reserve_labels(1, TRUE); @@ -1047,7 +1073,7 @@ END END domod; -PROCEDURE doimm (t: T; op: Op; imm: INTEGER; overwritesdest: BOOLEAN) = +PROCEDURE doimm (t: T; op: Op; READONLY imm: Target.Int; overwritesdest: BOOLEAN) = BEGIN unlock(t); @@ -1055,7 +1081,7 @@ IF (stop0.loc = OLoc.mem AND ((overwritesdest AND NOT stop0.mvar.var.stack_temp) OR CG_Bytes[stop0.mvar.t] = 2 OR - (CG_Bytes[stop0.mvar.t] = 1 AND (imm >= 16_80 OR imm <= -16_81)))) + (CG_Bytes[stop0.mvar.t] = 1 AND (TInt.GT(imm, TInt.MaxS8) OR TInt.LT(imm, TInt.MinS8))))) OR stop0.loc = OLoc.imm THEN find(t, stack0, Force.anyreg); ELSE @@ -1077,7 +1103,9 @@ unlock(t); WITH stack0 = pos(t, 0, "doneg"), stop0 = t.vstack[stack0] DO IF stop0.loc = OLoc.imm THEN - stop0.imm := -stop0.imm + IF NOT TInt.Negate(stop0.imm, stop0.imm) THEN + t.Warn("doneg: Negate overflowed"); + END; ELSE find(t, stack0, Force.anytemp); t.cg.unOp(Op.oNEG, stop0); @@ -1092,13 +1120,15 @@ BEGIN unlock(t); WITH stack0 = pos(t, 0, "doabs"), stop0 = t.vstack[stack0] DO - IF stop0.loc = OLoc.imm THEN - stop0.imm := ABS(stop0.imm) - ELSE + BEGIN (* IF stop0.loc = OLoc.imm THEN + IF NOT TInt.Abs(stop0.imm, stop0.imm) THEN + t.Err("doabs: Abs overflowed"); + END; + ELSE *) find(t, stack0, Force.anytemp); IF stop0.loc = OLoc.mem THEN - t.cg.immOp(Op.oCMP, stop0, 0); + t.cg.immOp(Op.oCMP, stop0, TZero); lab := t.cg.reserve_labels(1, TRUE); @@ -1124,28 +1154,37 @@ PROCEDURE doshift (t: T) = VAR ovflshift, leftlab, endlab: Label; + tShiftCount: Target.Int; + shiftCount: INTEGER; BEGIN unlock(t); WITH stack0 = pos(t, 0, "doshift"), stack1 = pos(t, 1, "doshift"), stop0 = t.vstack[stack0], stop1 = t.vstack[stack1] DO + IF stop0.loc = OLoc.imm THEN IF stop1.loc = OLoc.imm THEN - stop1.imm := Word.Shift(stop1.imm, stop0.imm); + IF NOT TInt.ToInt(stop0.imm, shiftCount) THEN + t.Err("doshift: unable to convert target integer to host integer"); + END; + TWord.Shift(stop1.imm, shiftCount, stop1.imm); ELSE - IF stop0.imm # 0 THEN + IF TInt.NE(stop0.imm, TZero) THEN find(t, stack1, Force.anytemp); - IF stop0.imm > 0 THEN - IF stop0.imm > 31 THEN + IF TInt.GT(stop0.imm, TZero) THEN + IF TInt.GT(stop0.imm, TInt.ThirtyOne) THEN t.cg.binOp(Op.oXOR, stop1, stop1); ELSE t.cg.immOp(Op.oSAL, stop1, stop0.imm); END ELSE - IF stop0.imm < -31 THEN + IF TInt.LT(stop0.imm, TInt.MThirtyOne) THEN t.cg.binOp(Op.oXOR, stop1, stop1); ELSE - t.cg.immOp(Op.oSHR, stop1, -stop0.imm); + IF NOT TInt.Negate(stop0.imm, tShiftCount) THEN + t.Err("doshift: Negate overflowed"); + END; + t.cg.immOp(Op.oSHR, stop1, tShiftCount); END END; @@ -1154,7 +1193,7 @@ END ELSE - IF ((stop1.loc # OLoc.imm) OR (stop1.imm # 0)) THEN + IF ((stop1.loc # OLoc.imm) OR (TInt.NE(stop1.imm, TZero))) THEN find(t, stack0, Force.regset, RegSet {Codex86.ECX}); @@ -1163,7 +1202,7 @@ find(t, stack1, Force.anyreg); END; - t.cg.immOp(Op.oCMP, stop0, 0); + t.cg.immOp(Op.oCMP, stop0, TZero); leftlab := t.cg.reserve_labels(1, TRUE); ovflshift := t.cg.reserve_labels(1, TRUE); @@ -1171,7 +1210,7 @@ t.cg.brOp(Cond.GE, leftlab); t.cg.unOp(Op.oNEG, stop0); - t.cg.immOp(Op.oCMP, stop0, 32); + t.cg.immOp(Op.oCMP, stop0, TInt.ThirtyTwo); t.cg.brOp(Cond.GE, ovflshift); t.cg.unOp(Op.oSHR, stop1); t.cg.brOp(Cond.Always, endlab); @@ -1181,7 +1220,7 @@ t.cg.brOp(Cond.Always, endlab); t.cg.set_label(leftlab); (* .leftlab *) - t.cg.immOp(Op.oCMP, stop0, 32); + t.cg.immOp(Op.oCMP, stop0, TInt.ThirtyTwo); t.cg.brOp(Cond.GE, ovflshift); t.cg.unOp(Op.oSAL, stop1); t.cg.set_label(endlab); @@ -1198,22 +1237,29 @@ PROCEDURE dorotate (t: T) = VAR leftlab, endlab: Label; + rotateCount: INTEGER; BEGIN unlock(t); WITH stack0 = pos(t, 0, "dorotate"), stack1 = pos(t, 1, "dorotate"), stop0 = t.vstack[stack0], stop1 = t.vstack[stack1] DO IF stop0.loc = OLoc.imm THEN IF stop1.loc = OLoc.imm THEN - stop1.imm := Word.Rotate(stop1.imm, stop0.imm); + IF NOT TInt.ToInt(stop0.imm, rotateCount) THEN + t.Err("dorotate: failed to convert rotateCount to host integer"); + END; + TWord.Rotate(stop1.imm, rotateCount, stop1.imm); ELSE - IF stop0.imm # 0 THEN + IF TInt.NE(stop0.imm, TZero) THEN find(t, stack1, Force.anytemp); - IF stop0.imm > 0 THEN - stop0.imm := Word.And(stop0.imm, 16_1F); + IF TInt.GT(stop0.imm, TZero) THEN + TWord.And(stop0.imm, TInt.ThirtyOne, stop0.imm); t.cg.immOp(Op.oROL, stop1, stop0.imm); ELSE - stop0.imm := Word.And(-stop0.imm, 16_1F); + IF NOT TInt.Negate(stop0.imm, stop0.imm) THEN + t.Err("dorotate: negate overflowed"); + END; + TWord.And(stop0.imm, TInt.ThirtyOne, stop0.imm); t.cg.immOp(Op.oROR, stop1, stop0.imm); END; @@ -1228,7 +1274,7 @@ find(t, stack1, Force.anyreg); END; - t.cg.immOp(Op.oCMP, stop0, 0); + t.cg.immOp(Op.oCMP, stop0, TZero); leftlab := t.cg.reserve_labels(1, TRUE); endlab := t.cg.reserve_labels(1, TRUE); @@ -1253,6 +1299,7 @@ PROCEDURE doextract (t: T; sign: BOOLEAN) = VAR tbl: MVar; + int: INTEGER; BEGIN unlock(t); WITH stack0 = pos(t, 0, "extract"), stack1 = pos(t, 1, "extract"), @@ -1262,7 +1309,10 @@ IF stop0.loc = OLoc.imm THEN discard(t, 1); - doextract_n(t, sign, stop0.imm); + IF NOT TInt.ToInt(stop0.imm, int) THEN + t.Err("doextract: failed to convert to host integer"); + END; + doextract_n(t, sign, int); RETURN; END; @@ -1289,7 +1339,7 @@ ELSE IF stop1.loc = OLoc.imm THEN - stop1.imm := Word.And(stop1.imm, 16_1F); + TWord.And(stop1.imm, TInt.ThirtyOne, stop1.imm); ELSE find(t, stack1, Force.regset, RegSet { Codex86.ECX }); END; @@ -1316,6 +1366,8 @@ END doextract; PROCEDURE doextract_n (t: T; sign: BOOLEAN; n: INTEGER) = + VAR tn, t32MinusN, andval: Target.Int; + int: INTEGER; BEGIN unlock(t); WITH stack0 = pos(t, 0, "extract_n"), stack1 = pos(t, 1, "extract_n"), @@ -1323,7 +1375,10 @@ IF stop0.loc = OLoc.imm THEN discard(t, 1); - doextract_mn(t, sign, stop0.imm, n); + IF NOT TInt.ToInt(stop0.imm, int) THEN + t.Err("doextract_n: failed to convert to host integer"); + END; + doextract_mn(t, sign, int, n); RETURN; END; @@ -1337,12 +1392,20 @@ find(t, stack0, Force.anyreg); END; + IF NOT TInt.FromInt(n, Target.Integer.bytes, tn) THEN + t.Err("doextract_n: failed to convert n to target integer"); + END; + + IF NOT TInt.Subtract(TInt.ThirtyTwo, tn, t32MinusN) THEN + t.Err("doextract_n: Subtract overflowed"); + END; + t.cg.movImm(t.cg.reg[Codex86.ECX], 32 - n); t.cg.binOp(Op.oSUB, t.cg.reg[Codex86.ECX], stop0); t.cg.unOp(Op.oSAL, stop1); IF n < 32 THEN - t.cg.immOp(Op.oSAR, stop1, 32 - n); + t.cg.immOp(Op.oSAR, stop1, t32MinusN); END ELSE find(t, stack0, Force.regset, RegSet { Codex86.ECX }); @@ -1351,9 +1414,8 @@ t.cg.unOp(Op.oSHR, stop1); IF n < 32 THEN - WITH andval = Word.Shift(16_ffffffff, n - 32) DO - t.cg.immOp(Op.oAND, stop1, andval); - END + TWord.Shift(TInt.FFFFFFFF, n - 32, andval); + t.cg.immOp(Op.oAND, stop1, andval); END END; @@ -1363,16 +1425,21 @@ END doextract_n; PROCEDURE doextract_mn (t: T; sign: BOOLEAN; m, n: INTEGER) = + VAR andval, tint: Target.Int; BEGIN unlock(t); WITH stack0 = pos(t, 0, "extract_mn"), stop0 = t.vstack[stack0] DO - IF stop0.loc = OLoc.imm THEN - stop0.imm := Word.Shift(stop0.imm, -m); - stop0.imm := Word.And(stop0.imm, Word.Shift(16_FFFFFFFF, n - 32)); - - IF sign AND Word.And(stop0.imm, Word.Shift(1, n-1)) # 0 THEN - stop0.imm := Word.Or(stop0.imm, Word.Shift(16_FFFFFFFF, n)); + TWord.Shift(stop0.imm, -m, stop0.imm); + TWord.Shift(TInt.FFFFFFFF, n - 32, tint); + TWord.And(stop0.imm, tint, stop0.imm); + IF sign THEN + TWord.Shift(TInt.One, n - 1, tint); + TWord.And(stop0.imm, tint, tint); + IF TInt.NE(tint, TZero) THEN + TWord.Shift(TInt.FFFFFFFF, n, tint); + TWord.Or(stop0.imm, tint, stop0.imm); + END; END; RETURN; END; @@ -1380,22 +1447,30 @@ IF sign THEN find(t, stack0, Force.anyreg); IF (m + n) < 32 THEN - t.cg.immOp(Op.oSAL, stop0, 32 - (m + n)); + IF NOT TInt.FromInt(32 - (m + n), Target.Integer.bytes, tint) THEN + t.Err("doextract_mn: failed to convert 32 - (m + n) to target integer"); + END; + t.cg.immOp(Op.oSAL, stop0, tint); END; IF n < 32 THEN - t.cg.immOp(Op.oSAR, stop0, 32 - n); + IF NOT TInt.FromInt(32 - n, Target.Integer.bytes, tint) THEN + t.Err("doextract_mn: failed to convert 32 - n to target integer"); + END; + t.cg.immOp(Op.oSAR, stop0, tint); END ELSE find(t, stack0, Force.anyreg); IF (m + n) < 32 THEN - WITH andval = Word.Shift(16_ffffffff, m + n - 32) DO - t.cg.immOp(Op.oAND, stop0, andval); - END + TWord.Shift(TInt.FFFFFFFF, m + n - 32, andval); + t.cg.immOp(Op.oAND, stop0, andval); END; IF m > 0 THEN - t.cg.immOp(Op.oSHR, stop0, m); + IF NOT TInt.FromInt(m, Target.Integer.bytes, tint) THEN + t.Err("doextract_mn: failed to m to target integer"); + END; + t.cg.immOp(Op.oSHR, stop0, tint); END END; @@ -1405,6 +1480,8 @@ PROCEDURE doinsert (t: T) = VAR maskreg: Regno; tbl: MVar; + int: INTEGER; + tint: Target.Int; BEGIN unlock(t); WITH stack0 = pos(t, 0, "insert"), stack1 = pos(t, 1, "insert"), @@ -1414,12 +1491,15 @@ IF stop0.loc = OLoc.imm THEN discard(t, 1); - doinsert_n(t, stop0.imm); + IF NOT TInt.ToInt(stop0.imm, int) THEN + t.Err("doinsert: failed to convert to host integer"); + END; + doinsert_n(t, int); RETURN; END; IF stop1.loc = OLoc.imm THEN - stop1.imm := Word.And(stop1.imm, 16_1f); + TWord.And(stop1.imm, TInt.ThirtyOne, stop1.imm); ELSE find(t, stack1, Force.regset, RegSet { Codex86.ECX }); END; @@ -1444,7 +1524,7 @@ t.cg.binOp(Op.oAND, stop2, t.cg.reg[maskreg]); IF stop1.loc = OLoc.imm THEN - IF stop1.imm # 0 THEN + IF TInt.NE(stop1.imm, TZero) THEN t.cg.immOp(Op.oSAL, stop2, stop1.imm); t.cg.immOp(Op.oADD, stop0, stop1.imm); END @@ -1457,8 +1537,11 @@ t.cg.tableOp(Op.oMOV, t.cg.reg[maskreg], stop0, 4, tbl); IF stop1.loc = OLoc.imm THEN - t.cg.immOp(Op.oXOR, t.cg.reg[maskreg], - Word.Shift(16_FFFFFFFF, stop1.imm)); + IF NOT TInt.ToInt(stop1.imm, int) THEN + t.Err("failed to convert stop1.imm to host integer"); + END; + TWord.Shift(TInt.FFFFFFFF, int, tint); + t.cg.immOp(Op.oXOR, t.cg.reg[maskreg], tint); ELSE ImportHighSet (t, tbl); t.cg.tableOp(Op.oXOR, t.cg.reg[maskreg], stop1, 4, tbl); @@ -1476,6 +1559,8 @@ PROCEDURE doinsert_n (t: T; n: INTEGER) = VAR tbl: MVar; maskreg: Regno; + m: INTEGER; + tint: Target.Int; BEGIN unlock(t); WITH stack0 = pos(t, 0, "insert"), stack1 = pos(t, 1, "insert"), @@ -1485,7 +1570,10 @@ IF stop0.loc = OLoc.imm THEN discard(t, 1); - doinsert_mn(t, stop0.imm, n); + IF NOT TInt.ToInt(stop0.imm, m) THEN + t.Err("doinsert_n: failed to convert to host integer"); + END; + doinsert_mn(t, m, n); RETURN; END; @@ -1501,7 +1589,8 @@ corrupt(t, maskreg); IF n # 32 THEN - t.cg.immOp(Op.oAND, stop1, Word.Shift(16_ffffffff, n - 32)); + TWord.Shift(TInt.FFFFFFFF, n - 32, tint); + t.cg.immOp(Op.oAND, stop1, tint); END; t.cg.unOp(Op.oSAL, stop1); @@ -1528,6 +1617,7 @@ END doinsert_n; PROCEDURE doinsert_mn (t: T; m, n: INTEGER) = + VAR tm, tint: Target.Int; BEGIN unlock(t); WITH stack0 = pos(t, 0, "insert"), stack1 = pos(t, 1, "insert"), @@ -1540,41 +1630,49 @@ find(t, stack1, Force.anyreg); END; + TWord.Shift(TInt.FFFFFFFF, n - 32, tint); + IF NOT TInt.FromInt(m, Target.Integer.bytes, tm) THEN + t.Err("doinsert_mn: unable to convert m to target integer"); + END; + IF stop0.loc = OLoc.imm THEN - stop0.imm := Word.And(stop0.imm, Word.Shift(16_FFFFFFFF, n - 32)); - stop0.imm := Word.Shift(stop0.imm, m); + TWord.And(stop0.imm, tint, stop0.imm); + TWord.Shift(stop0.imm, m, stop0.imm); ELSE IF (n + m) < 32 THEN - t.cg.immOp(Op.oAND, stop0, Word.Shift(16_ffffffff, n - 32)); + t.cg.immOp(Op.oAND, stop0, tint); END; IF m # 0 THEN - t.cg.immOp(Op.oSAL, stop0, m); + t.cg.immOp(Op.oSAL, stop0, tm); END END; WITH mask = Word.Xor(Word.Shift(16_ffffffff, m), Word.Shift(16_ffffffff, m + n - 32)) DO IF mask # 16_ffffffff THEN + IF NOT TInt.FromInt(mask, Target.Integer.bytes, tint) THEN + t.Err("doinsert_mn: unable to convert mask to target integer"); + END; IF stop1.loc = OLoc.imm THEN - stop1.imm := Word.And(stop1.imm, mask); + TWord.And(stop1.imm, tint, stop1.imm); ELSE - t.cg.immOp(Op.oAND, stop1, mask); + t.cg.immOp(Op.oAND, stop1, tint); END END END; IF stop1.loc = OLoc.imm THEN IF stop0.loc = OLoc.imm THEN - stop1.imm := Word.Or(stop1.imm, stop0.imm); + TWord.Or(stop1.imm, stop0.imm, stop1.imm); ELSE swap(t); - IF stop0.loc # OLoc.imm OR stop0.imm # 0 THEN + IF stop0.loc # OLoc.imm OR TInt.NE(stop0.imm, TZero) THEN t.cg.binOp(Op.oOR, stop1, stop0); END END ELSE - IF stop0.loc # OLoc.imm OR stop0.imm # 0 THEN + IF stop0.loc # OLoc.imm OR TInt.NE(stop0.imm, TZero) THEN t.cg.binOp(Op.oOR, stop1, stop0); END END; @@ -1658,7 +1756,16 @@ PROCEDURE doindex_address (t: T; shift, size: INTEGER; neg: BOOLEAN) = VAR imsize: INTEGER; muldest: Regno; + tsize: Target.Int; + tshift: Target.Int; BEGIN + IF NOT TInt.FromInt(size, Target.Integer.bytes, tsize) THEN + t.Err("doindex_address: failed to convert size to target integer"); + END; + IF NOT TInt.FromInt(shift, Target.Integer.bytes, tshift) THEN + t.Err("doindex_address: failed to convert size to target integer"); + END; + unlock(t); WITH stack0 = pos(t, 0, "doindex_address"), stack1 = pos(t, 1, "doindex_address"), @@ -1667,7 +1774,13 @@ find(t, stack1, Force.anyreg, RegSet {}, TRUE); IF stop0.loc = OLoc.imm THEN - stop0.imm := stop0.imm * size; + + (* Beware TWord.Multiply: x * 1 = 0 *) + + IF NOT TInt.Multiply(stop0.imm, tsize, stop0.imm) THEN + t.Err("doindex_address: multiply overflowed"); + END; + ELSE IF stop0.loc # OLoc.register AND shift >= 0 THEN find(t, stack0, Force.anyreg); @@ -1696,7 +1809,7 @@ END ELSIF shift > 0 THEN - t.cg.immOp(Op.oSAL, stop0, shift); + t.cg.immOp(Op.oSAL, stop0, tshift); newdest(t, stop0); END END; @@ -1833,9 +1946,9 @@ t.cg.memFOp(FOp.fSTCW, statusop.mvar); t.cg.movOp(t.cg.reg[statreg], statusop); - t.cg.immOp(Op.oAND, t.cg.reg[statreg], 16_0000F3FF); + t.cg.immOp(Op.oAND, t.cg.reg[statreg], TInt.F3FF); - IF t.rmode[mode] # 0 THEN + IF TInt.NE(t.rmode[mode], TZero) THEN t.cg.immOp(Op.oOR, t.cg.reg[statreg], t.rmode[mode]); END; @@ -1880,8 +1993,8 @@ IF op.loc = OLoc.register THEN WITH z = t.reguse[op.reg] DO z.last_store := NoStore; - z.upbound := LAST (INTEGER); - z.lowbound := FIRST (INTEGER); + z.upbound := Target.Integer.max; + z.lowbound := Target.Integer.min; z.imm := FALSE; z.non_nil := FALSE; END; @@ -1928,22 +2041,22 @@ RETURN t.vstack[stackp].reg; END reg; -PROCEDURE lower (t: T; reg: Regno): INTEGER = +PROCEDURE lower (t: T; reg: Regno): Target.Int = BEGIN RETURN t.reguse[reg].lowbound; END lower; -PROCEDURE upper (t: T; reg: Regno): INTEGER = +PROCEDURE upper (t: T; reg: Regno): Target.Int = BEGIN RETURN t.reguse[reg].upbound; END upper; -PROCEDURE set_lower (t: T; reg: Regno; newlow: INTEGER) = +PROCEDURE set_lower (t: T; reg: Regno; newlow: Target.Int) = BEGIN t.reguse[reg].lowbound := newlow; END set_lower; -PROCEDURE set_upper (t: T; reg: Regno; newup: INTEGER) = +PROCEDURE set_upper (t: T; reg: Regno; newup: Target.Int) = BEGIN t.reguse[reg].upbound := newup; END set_upper; @@ -1977,16 +2090,16 @@ WITH z = t.reguse[i] DO z.stackp := -1; z.last_store := NoStore; - z.upbound := LAST (INTEGER); - z.lowbound := FIRST (INTEGER); + z.upbound := Target.Integer.max; + z.lowbound := Target.Integer.min; z.imm := FALSE; z.non_nil := FALSE; z.locked := FALSE; END; END; - t.rmode := ARRAY FlToInt OF INTEGER - { 16_0000, 16_0400, 16_0800, 16_0F00 }; + t.rmode := ARRAY FlToInt OF Target.Int + { TZero, TInt.x0400, TInt.x0800, TInt.x0F00 }; t.lowset_table := NIL; t.highset_table := NIL; END init; @@ -2068,7 +2181,7 @@ wr.OutT (OLocName [op.loc]); wr.OutT (" mvar: "); DebugMVar (op.mvar, wr); wr.OutT (" reg: "); wr.OutT (RegName [op.reg]); - wr.OutT (" imm: "); wr.OutI (op.imm); + wr.OutT (" imm: "); wr.OutT (TInt.ToText (op.imm)); wr.OutT (" stackp: "); wr.OutI (op.stackp); IF (op.opcode) THEN wr.OutT (" OPCODE"); END; END DebugOp; @@ -2081,14 +2194,14 @@ IF r.last_store # NoStore THEN wr.OutT (" mvar: "); DebugMVar (r.last_store, wr); END; - IF (r.last_imm # 0) THEN - wr.OutT (" imm: "); wr.OutI (r.last_imm); + IF (NOT TInt.EQ(r.last_imm, TZero)) THEN + wr.OutT (" imm: "); wr.OutT (TInt.ToText (r.last_imm)); END; - IF (r.lowbound # FIRST (INTEGER)) THEN - wr.OutT (" lo: "); wr.OutI (r.lowbound); + IF (NOT TInt.EQ(r.lowbound, Target.Integer.min)) THEN + wr.OutT (" lo: "); wr.OutT (TInt.ToText (r.lowbound)); END; - IF (r.upbound # LAST (INTEGER)) THEN - wr.OutT (" hi: "); wr.OutI (r.upbound); + IF (NOT TInt.EQ(r.upbound, Target.Integer.max)) THEN + wr.OutT (" hi: "); wr.OutT (TInt.ToText (r.upbound)); END; IF (r.imm # FALSE) THEN wr.OutT (" IMMED"); Index: m3middle/src/TInt.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/TInt.i3,v retrieving revision 1.16 diff -u -r1.16 TInt.i3 --- m3middle/src/TInt.i3 18 Jan 2010 14:25:00 -0000 1.16 +++ m3middle/src/TInt.i3 20 Jan 2010 14:55:05 -0000 @@ -21,46 +21,46 @@ FROM Target IMPORT Int, IBytes; CONST - F = 16_0F; - FF = 16_FF; - F3 = 16_F3; - - Zero = Int{NUMBER (IBytes), IBytes{0,0,..}}; - One = Int{NUMBER (IBytes), IBytes{1,0,..}}; - Two = Int{NUMBER (IBytes), IBytes{2,0,..}}; - Three = Int{NUMBER (IBytes), IBytes{3,0,..}}; - Four = Int{NUMBER (IBytes), IBytes{4,0,..}}; - Eight = Int{NUMBER (IBytes), IBytes{8,0,..}}; - Ten = Int{NUMBER (IBytes), IBytes{10,0,..}}; - ThirtyOne = Int{NUMBER (IBytes), IBytes{31,0,..}}; - ThirtyTwo = Int{NUMBER (IBytes), IBytes{32,0,..}}; - F3FF = Int{NUMBER (IBytes), IBytes{FF,F3,0,..}}; - x0400 = Int{NUMBER (IBytes), IBytes{0,4,0,..}}; - x0800 = Int{NUMBER (IBytes), IBytes{0,8,0,..}}; - x0F00 = Int{NUMBER (IBytes), IBytes{0,F,0,..}}; + Zero = Int{NUMBER (IBytes), IBytes{16_00,..}}; + One = Int{NUMBER (IBytes), IBytes{16_01,16_00,..}}; + Two = Int{NUMBER (IBytes), IBytes{16_02,16_00,..}}; + Three = Int{NUMBER (IBytes), IBytes{16_03,16_00,..}}; + Four = Int{NUMBER (IBytes), IBytes{16_04,16_00,..}}; + Eight = Int{NUMBER (IBytes), IBytes{16_08,16_00,..}}; + Ten = Int{NUMBER (IBytes), IBytes{16_0A,16_00,..}}; + ThirtyOne = Int{NUMBER (IBytes), IBytes{16_1F,16_00,..}}; + ThirtyTwo = Int{NUMBER (IBytes), IBytes{16_20,16_00,..}}; + F3FF = Int{NUMBER (IBytes), IBytes{16_FF,16_F3,16_00,..}}; + x0400 = Int{NUMBER (IBytes), IBytes{16_00,16_04,16_00,..}}; + x0800 = Int{NUMBER (IBytes), IBytes{16_00,16_08,16_00,..}}; + x0F00 = Int{NUMBER (IBytes), IBytes{16_00,16_0F,16_00,..}}; + FF = MaxU8; + FFFF = MaxU16; + FFFFFFFF = MaxU32; (* 'M' for Minus (negative) *) - MOne = Int{NUMBER (IBytes), IBytes{FF,..}}; + MOne = Int{NUMBER (IBytes), IBytes{16_FF,..}}; + MThirtyOne = Int{NUMBER (IBytes), IBytes{16_E1,16_FF,..}}; (* Minimum and Maximum values for Signed and Unsigned values with specified bit count. *) - MinS8 = Int{NUMBER (IBytes), IBytes{16_80,FF,..}}; - MinS16 = Int{NUMBER (IBytes), IBytes{0,16_80,FF,..}}; - MinS32 = Int{NUMBER (IBytes), IBytes{0,0,0,16_80,FF,..}}; - MinS64 = Int{NUMBER (IBytes), IBytes{0,0,0,0,0,0,0,16_80}}; - MaxS8 = Int{NUMBER (IBytes), IBytes{16_7F,0,..}}; - MaxS16 = Int{NUMBER (IBytes), IBytes{FF,16_7F,0,..}}; - MaxS32 = Int{NUMBER (IBytes), IBytes{FF,FF,FF,16_7F,0,..}}; - MaxS64 = Int{NUMBER (IBytes), IBytes{FF,FF,FF,FF,FF,FF,FF,16_7F}}; + MinS8 = Int{NUMBER (IBytes), IBytes{16_80,16_FF,..}}; + MinS16 = Int{NUMBER (IBytes), IBytes{16_00,16_80,16_FF,..}}; + MinS32 = Int{NUMBER (IBytes), IBytes{16_00,16_00,16_00,16_80,16_FF,..}}; + MinS64 = Int{NUMBER (IBytes), IBytes{16_00,16_00,16_00,16_00,16_00,16_00,16_00,16_80}}; + MaxS8 = Int{NUMBER (IBytes), IBytes{16_7F,16_00,..}}; + MaxS16 = Int{NUMBER (IBytes), IBytes{16_FF,16_7F,16_00,..}}; + MaxS32 = Int{NUMBER (IBytes), IBytes{16_FF,16_FF,16_FF,16_7F,16_00,..}}; + MaxS64 = Int{NUMBER (IBytes), IBytes{16_FF,16_FF,16_FF,16_FF,16_FF,16_FF,16_FF,16_7F}}; MinU8 = Zero; MinU16 = Zero; MinU32 = Zero; MinU64 = Zero; - MaxU8 = Int{NUMBER (IBytes), IBytes{FF,0,..}}; - MaxU16 = Int{NUMBER (IBytes), IBytes{FF,FF,0,..}}; - MaxU32 = Int{NUMBER (IBytes), IBytes{FF,FF,FF,FF,0,..}}; - MaxU64 = Int{NUMBER (IBytes), IBytes{FF,FF,FF,FF,FF,FF,FF,FF}}; + MaxU8 = Int{NUMBER (IBytes), IBytes{16_FF,16_00,..}}; + MaxU16 = Int{NUMBER (IBytes), IBytes{16_FF,16_FF,16_00,..}}; + MaxU32 = Int{NUMBER (IBytes), IBytes{16_FF,16_FF,16_FF,16_FF,16_00,..}}; + MaxU64 = Int{NUMBER (IBytes), IBytes{16_FF,16_FF,16_FF,16_FF,16_FF,16_FF,16_FF,16_FF}}; PROCEDURE FromInt (x: INTEGER; n: CARDINAL; VAR i: Int): BOOLEAN; (* converts a host integer 'x' to a target integer 'i' *) @@ -76,6 +76,9 @@ (* converts the string of decimal characters in 'chars' to an integer value in 'i' *) +PROCEDURE Abs (READONLY a: Int; VAR r: Int): BOOLEAN; +(* returns a if a >= 0, -a if a < 0, or overflow *) + PROCEDURE Add (READONLY a, b: Int; VAR i: Int): BOOLEAN; (* returns 'a + b' unless there's an overflow *) Index: m3middle/src/TInt.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/TInt.m3,v retrieving revision 1.13 diff -u -r1.13 TInt.m3 --- m3middle/src/TInt.m3 18 Jan 2010 11:12:25 -0000 1.13 +++ m3middle/src/TInt.m3 20 Jan 2010 14:55:05 -0000 @@ -150,6 +150,15 @@ RETURN Subtract(Zero, a, r); END Negate; +PROCEDURE Abs (READONLY a: Int; VAR r: Int): BOOLEAN = + (* It is safe for r to alias a *) + BEGIN + IF GE(a, Zero) THEN + RETURN FALSE; + END; + RETURN Negate(a, r); + END Abs; + PROCEDURE Multiply (READONLY a, b: Int; VAR r: Int): BOOLEAN = VAR n := MIN (a.n, b.n); k, carry: INTEGER; q: Int;