? t1 Index: Codex86.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Codex86.i3,v retrieving revision 1.32 diff -u -r1.32 Codex86.i3 --- Codex86.i3 27 Feb 2010 00:49:43 -0000 1.32 +++ Codex86.i3 27 Feb 2010 12:33:14 -0000 @@ -8,7 +8,7 @@ INTERFACE Codex86; -IMPORT M3CG, M3ObjFile, TFloat, TIntN; +IMPORT M3CG, M3ObjFile, TFloat, Target; FROM M3CG IMPORT MType, Label, ByteOffset; FROM M3CG_Ops IMPORT ErrorHandler; IMPORT M3x86Rep, Wrx86; @@ -45,14 +45,14 @@ fstack_swap (); fstack_discard (); f_loadlit (READONLY flarr: FloatBytes; type: MType); - immOp (op: Op; READONLY dest: Operand; READONLY imm: TIntN.T); + immOp (op: Op; READONLY dest: Operand; READONLY imm: Target.IntN); binOp (op: Op; READONLY dest, src: Operand); tableOp (op: Op; READONLY dest, index: Operand; scale: INTEGER; table: MVar); swapOp (READONLY dest, src: Operand); movOp (READONLY dest, src: Operand); movDummyReloc (READONLY dest: Operand; sym: INTEGER); - movImmT (READONLY dest: Operand; imm: TIntN.T); + movImmT (READONLY dest: Operand; imm: Target.IntN); movImmI (READONLY dest: Operand; imm: INTEGER); MOVSWOp (); STOSWOp (); Index: Codex86.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Codex86.m3,v retrieving revision 1.94 diff -u -r1.94 Codex86.m3 --- Codex86.m3 27 Feb 2010 00:49:43 -0000 1.94 +++ Codex86.m3 27 Feb 2010 12:33:14 -0000 @@ -18,7 +18,7 @@ FROM M3CG_Ops IMPORT ErrorHandler; FROM M3x86Rep IMPORT Operand, MVar, Regno, OLoc, VLoc, x86Var, x86Proc, NRegs, OperandSize, GetOperandSize; -FROM M3x86Rep IMPORT RegistersForByteOperations, RegName, SplitOperand, Types64, SplitImm, OperandPart, GetTypeSize, TZero; +FROM M3x86Rep IMPORT RegistersForByteOperations, RegName, SplitOperand, Is64, SplitImm, OperandPart, GetTypeSize, TZero; FROM M3x86Rep IMPORT EAX, EDX, ESP, EBP, ECX; FROM M3ObjFile IMPORT Seg; @@ -252,7 +252,7 @@ BEGIN <* ASSERT (op.loc = OLoc.register AND op.reg[0] IN RegistersForByteOperations ) OR - (op.loc = OLoc.mem AND CG_Bytes[op.mvar.type] = 1) *> + (op.loc = OLoc.mem AND CG_Bytes[op.mvar.mvar_type] = 1) *> IF op.loc = OLoc.register THEN movImmT(t, op, TZero); END; @@ -329,12 +329,12 @@ prepare_stack(t, op); IF t.ftop_inmem THEN Mn(t, fopcode[op].name, " ST"); MnMVar(t, t.ftop_mem); - IF t.ftop_mem.type = Type.Reel THEN + IF t.ftop_mem.mvar_type = Type.Reel THEN mem.opcode := fopcode[op].m32; ELSE mem.opcode := fopcode[op].m64; END; - build_modrm(t, Operand {loc := OLoc.mem, mvar := t.ftop_mem, optype := t.ftop_mem.type}, + build_modrm(t, Operand {loc := OLoc.mem, mvar := t.ftop_mem, optype := t.ftop_mem.mvar_type}, t.opcode[fopcode[op].memop], mem); writecode(t, mem); log_global_var(t, t.ftop_mem, -4); @@ -362,7 +362,7 @@ prepare_stack(t, op); Mn(t, fopcode[op].name, " m"); MnMVar(t, mvar); - build_modrm(t, Operand {loc := OLoc.mem, mvar := mvar, optype := mvar.type}, + build_modrm(t, Operand {loc := OLoc.mem, mvar := mvar, optype := mvar.mvar_type}, t.opcode[fopcode[op].memop], ins); ins.opcode := fopcode[op].m32; writecode(t, ins); @@ -379,16 +379,16 @@ writecode(t, ins); END noargOp; -PROCEDURE immOp1 (t: T; op: Op; READONLY dest: Operand; READONLY imm: TIntN.T) = +PROCEDURE immOp1 (t: T; op: Op; READONLY dest: Operand; READONLY imm: Target.IntN) = VAR ins: Instruction; BEGIN <* ASSERT dest.loc = OLoc.register OR dest.loc = OLoc.mem *> - IF NOT TIntN.ToInt(imm, ins.imm) THEN + IF NOT TIntN.ToHostInteger(imm, ins.imm) THEN t.Err("immOp1: unable to convert immediate to INTEGER:" & TIntN.ToDiagnosticText(imm)); END; - IF TIntN.GE(imm, TIntN.Min8) AND TIntN.LE(imm, TIntN.Min8) THEN + IF TIntN.GE(imm, Target.Int8.minN) AND TIntN.LE(imm, Target.Int8.maxN) THEN ins.imsize := 1; ELSE ins.imsize := 4; @@ -402,11 +402,11 @@ ELSE build_modrm(t, dest, t.opcode[opcode[op].immop], ins); IF ins.imsize = 1 THEN - IF dest.loc = OLoc.mem AND CG_Bytes[dest.mvar.type] = 1 THEN + IF dest.loc = OLoc.mem AND CG_Bytes[dest.mvar.mvar_type] = 1 THEN ins.opcode := opcode[op].imm32 - 1; writecode(t, ins); log_global_var(t, dest.mvar, -5); - ELSIF dest.loc = OLoc.mem AND CG_Bytes[dest.mvar.type] = 2 THEN + ELSIF dest.loc = OLoc.mem AND CG_Bytes[dest.mvar.mvar_type] = 2 THEN ins.prefix := TRUE; ins.opcode := opcode[op].imm8; writecode(t, ins); @@ -427,7 +427,7 @@ END END ELSE - <* ASSERT dest.loc # OLoc.mem OR CG_Bytes[dest.mvar.type] = 4 *> + <* ASSERT dest.loc # OLoc.mem OR CG_Bytes[dest.mvar.mvar_type] = 4 *> ins.opcode := opcode[op].imm32; writecode(t, ins); IF dest.loc = OLoc.mem THEN @@ -437,19 +437,19 @@ END END immOp1; -PROCEDURE immOp (t: T; op: Op; READONLY dest: Operand; READONLY imm: TIntN.T) = +PROCEDURE immOp (t: T; op: Op; READONLY dest: Operand; READONLY imm: Target.IntN) = VAR destA: ARRAY OperandPart OF Operand; - immA: ARRAY OperandPart OF TIntN.T; + immA: ARRAY OperandPart OF Target.IntN; immSize := SplitImm(dest.optype, imm, immA); destSize := SplitOperand(dest, destA); compare_label: Label; - immMinus32: TIntN.T; + immMinus32: Target.IntN; shiftCount := Operand{loc := OLoc.imm, imm := imm}; BEGIN <* ASSERT immSize = destSize *> - <* ASSERT NOT destA[0].optype IN Types64 *> - <* ASSERT NOT destA[destSize - 1].optype IN Types64 *> + <* ASSERT NOT Is64(destA[0].optype) *> + <* ASSERT NOT Is64(destA[destSize - 1].optype) *> IF (immSize = 2) AND (op IN SET OF Op{Op.oCMP, Op.oADD, Op.oSUB, Op.oSHL, Op.oSHR}) THEN CASE op OF @@ -517,8 +517,8 @@ VAR ins: Instruction; BEGIN - <* ASSERT NOT src.optype IN Types64 *> - <* ASSERT NOT dest.optype IN Types64 *> + <* ASSERT NOT Is64(src.optype) *> + <* ASSERT NOT Is64(dest.optype) *> <* ASSERT dest.loc = OLoc.register OR dest.loc = OLoc.mem *> @@ -531,10 +531,10 @@ build_modrm(t, src, dest, ins); ins.opcode := opcode[op].rrm + 1; IF src.loc = OLoc.mem THEN - <* ASSERT CG_Bytes[src.mvar.type] = 4 *> + <* ASSERT CG_Bytes[src.mvar.mvar_type] = 4 *> END ELSE - <* ASSERT src.loc = OLoc.register AND CG_Bytes[src.mvar.type] = 4 *> + <* ASSERT src.loc = OLoc.register AND CG_Bytes[src.mvar.mvar_type] = 4 *> build_modrm(t, dest, src, ins); ins.opcode := opcode[op].rmr + 1; END; @@ -551,10 +551,10 @@ <* ASSERT src.loc = OLoc.register *> <* ASSERT shiftCount.loc = OLoc.register OR shiftCount.loc = OLoc.imm *> <* ASSERT shiftCount.loc # OLoc.register OR shiftCount.reg[0] = ECX *> - <* ASSERT shiftCount.loc # OLoc.imm OR (TIntN.GE(shiftCount.imm, TIntN.Min8) AND TIntN.LE(shiftCount.imm, TIntN.Max8)) *> + <* ASSERT shiftCount.loc # OLoc.imm OR (TIntN.GE(shiftCount.imm, Target.Int8.minN) AND TIntN.LE(shiftCount.imm, Target.Int8.maxN)) *> IF shiftCount.loc = OLoc.imm THEN - IF NOT TIntN.ToInt(shiftCount.imm, ins.imm) THEN + IF NOT TIntN.ToHostInteger(shiftCount.imm, ins.imm) THEN t.Err("binOp: unable to convert immediate to INTEGER:" & TIntN.ToDiagnosticText(shiftCount.imm)); END; ins.imsize := 1; @@ -587,10 +587,10 @@ compare_label: Label; BEGIN - <* ASSERT NOT srcA[0].optype IN Types64 *> - <* ASSERT NOT destA[0].optype IN Types64 *> - <* ASSERT NOT srcA[srcSize - 1].optype IN Types64 *> - <* ASSERT NOT destA[destSize - 1].optype IN Types64 *> + <* ASSERT NOT Is64(srcA[0].optype) *> + <* ASSERT NOT Is64(destA[0].optype) *> + <* ASSERT NOT Is64(srcA[srcSize - 1].optype) *> + <* ASSERT NOT Is64(destA[destSize - 1].optype) *> IF srcSize # destSize THEN t.Err("binOp: size mismatch: destSize:" & Fmt.Int(destSize) @@ -642,7 +642,7 @@ BEGIN <* ASSERT dest.loc = OLoc.register AND index.loc = OLoc.register *> - ins.disp := table.offset; + ins.disp := table.mvar_offset; IF table.var.loc = VLoc.temp THEN <* ASSERT table.var.parent = t.current_proc *> INC(ins.disp, table.var.offset); @@ -701,11 +701,11 @@ END; IF dest.loc = OLoc.register THEN - <* ASSERT src.loc = OLoc.register OR CG_Bytes[src.mvar.type] = 4 *> + <* ASSERT src.loc = OLoc.register OR CG_Bytes[src.mvar.mvar_type] = 4 *> build_modrm(t, src, dest, ins); ELSE <* ASSERT src.loc = OLoc.register *> - <* ASSERT dest.loc = OLoc.register OR CG_Bytes[dest.mvar.type] = 4 *> + <* ASSERT dest.loc = OLoc.register OR CG_Bytes[dest.mvar.mvar_type] = 4 *> build_modrm (t, dest, src, ins); END; Mn(t, "XCHG "); MnOp(t, dest); MnOp(t, src); @@ -733,10 +733,10 @@ END; <* ASSERT srcSize = destSize *> - <* ASSERT NOT srcA[0].optype IN Types64 *> - <* ASSERT NOT destA[0].optype IN Types64 *> - <* ASSERT NOT srcA[srcSize - 1].optype IN Types64 *> - <* ASSERT NOT destA[destSize - 1].optype IN Types64 *> + <* ASSERT NOT Is64(srcA[0].optype) *> + <* ASSERT NOT Is64(destA[0].optype) *> + <* ASSERT NOT Is64(srcA[srcSize - 1].optype) *> + <* ASSERT NOT Is64(destA[destSize - 1].optype) *> FOR i := 0 TO destSize - 1 DO swapOp1(t, destA[i], srcA[i]); @@ -799,10 +799,10 @@ RETURN; END; - IF dest.loc = OLoc.register AND dest.reg[0] = EAX AND src.loc = OLoc.mem AND CG_Bytes[src.mvar.type] = 4 AND src.mvar.var.loc = VLoc.global THEN + IF dest.loc = OLoc.register AND dest.reg[0] = EAX AND src.loc = OLoc.mem AND CG_Bytes[src.mvar.mvar_type] = 4 AND src.mvar.var.loc = VLoc.global THEN Mn(t, "MOV"); MnOp(t, dest); MnOp(t, src); ins.opcode := 16_A1; - ins.disp := src.mvar.offset; + ins.disp := src.mvar.mvar_offset; ins.dsize := 4; writecode (t, ins); log_global_var(t, src.mvar, -4); @@ -812,16 +812,16 @@ IF src.loc = OLoc.register AND src.reg[0] = EAX AND dest.loc = OLoc.mem AND dest.mvar.var.loc = VLoc.global THEN Mn(t, "MOV"); MnOp(t, dest); MnOp(t, src); ins.opcode := 16_A2; - get_op_size(dest.mvar.type, ins); - ins.disp := dest.mvar.offset; + get_op_size(dest.mvar.mvar_type, ins); + ins.disp := dest.mvar.mvar_offset; ins.dsize := 4; writecode(t, ins); log_global_var(t, dest.mvar, -4); RETURN; END; - IF dest.loc = OLoc.register AND src.loc = OLoc.mem AND CG_Bytes[src.mvar.type] < 4 THEN - CASE src.mvar.type OF + IF dest.loc = OLoc.register AND src.loc = OLoc.mem AND CG_Bytes[src.mvar.mvar_type] < 4 THEN + CASE src.mvar.mvar_type OF | Type.Word8 => ins.opcode := 16_8A; mnemonic := "MOV"; binOp(t, Op.oXOR, t.reg[dest.reg[0]], t.reg[dest.reg[0]]); @@ -846,7 +846,7 @@ build_modrm(t, src, dest, ins); ins.opcode := 16_8A; IF src.loc # OLoc.register THEN - get_op_size(src.mvar.type, ins); + get_op_size(src.mvar.mvar_type, ins); ELSE INC(ins.opcode); END @@ -854,7 +854,7 @@ <* ASSERT src.loc = OLoc.register *> build_modrm(t, dest, src, ins); ins.opcode := 16_88; - get_op_size(dest.mvar.type, ins); + get_op_size(dest.mvar.mvar_type, ins); END; Mn(t, "MOV"); MnOp(t, dest); MnOp(t, src); @@ -882,10 +882,10 @@ END; <* ASSERT srcSize = destSize *> - <* ASSERT NOT srcA[0].optype IN Types64 *> - <* ASSERT NOT destA[0].optype IN Types64 *> - <* ASSERT NOT srcA[srcSize - 1].optype IN Types64 *> - <* ASSERT NOT destA[destSize - 1].optype IN Types64 *> + <* ASSERT NOT Is64(srcA[0].optype) *> + <* ASSERT NOT Is64(destA[0].optype) *> + <* ASSERT NOT Is64(srcA[srcSize - 1].optype) *> + <* ASSERT NOT Is64(destA[destSize - 1].optype) *> FOR i := 0 TO destSize - 1 DO movOp1(t, destA[i], srcA[i]); @@ -908,21 +908,21 @@ t.obj.relocate(t.textsym, t.obj.cursor(Seg.Text) - 4, sym); END movDummyReloc; -PROCEDURE movImmT (t: T; READONLY dest: Operand; imm: TIntN.T) = +PROCEDURE movImmT (t: T; READONLY dest: Operand; imm: Target.IntN) = VAR ins: Instruction; BEGIN - IF NOT TIntN.ToInt(imm, ins.imm) THEN + IF NOT TIntN.ToHostInteger(imm, ins.imm) THEN t.Err("movImmT: unable to convert immediate to INTEGER:" & TIntN.ToDiagnosticText(imm)); END; IF dest.loc # OLoc.register THEN <* ASSERT dest.loc = OLoc.mem *> ins.opcode := 16_C6; - get_op_size(dest.mvar.type, ins); + get_op_size(dest.mvar.mvar_type, ins); build_modrm(t, dest, t.opcode[0], ins); Mn(t, "MOV"); MnOp(t, dest); MnImmTInt(t, imm); - ins.imsize := CG_Bytes[dest.mvar.type]; + ins.imsize := CG_Bytes[dest.mvar.mvar_type]; writecode(t, ins); - log_global_var(t, dest.mvar, -4 - CG_Bytes[dest.mvar.type]); + log_global_var(t, dest.mvar, -4 - CG_Bytes[dest.mvar.mvar_type]); ELSIF TIntN.EQ(imm, TZero) THEN binOp(t, Op.oXOR, dest, dest); ELSE @@ -934,10 +934,10 @@ END movImmT; PROCEDURE movImmI (t: T; READONLY dest: Operand; imm: INTEGER) = - VAR immT: TIntN.T; + VAR immT: Target.IntN; BEGIN - IF NOT TIntN.FromInt(imm, BYTESIZE(imm), immT) THEN - t.Err("movImmI: unable to convert INTEGER to TIntN.T"); + IF NOT TIntN.FromHostInteger(imm, BYTESIZE(imm), immT) THEN + t.Err("movImmI: unable to convert INTEGER to Target.IntN"); END; t.movImmT(dest, immT); END movImmI; @@ -949,7 +949,7 @@ CASE src.loc OF | OLoc.imm => ins.opcode := 16_68; - IF NOT TIntN.ToInt(src.imm, ins.imm) THEN + IF NOT TIntN.ToHostInteger(src.imm, ins.imm) THEN t.Err("pushOp: unable to convert immediate to INTEGER:" & TIntN.ToDiagnosticText(src.imm)); END; ins.imsize := 4; @@ -958,7 +958,7 @@ ins.opcode := 16_50 + src.reg[0]; writecode(t, ins); | OLoc.mem => - <* ASSERT CG_Bytes[src.mvar.type] = 4 *> + <* ASSERT CG_Bytes[src.mvar.mvar_type] = 4 *> build_modrm(t, src, t.opcode[6], ins); ins.opcode := 16_FF; writecode(t, ins); @@ -973,8 +973,8 @@ size := SplitOperand(src, a); BEGIN - <* ASSERT NOT a[0].optype IN Types64 *> - <* ASSERT NOT a[size - 1].optype IN Types64 *> + <* ASSERT NOT Is64(a[0].optype) *> + <* ASSERT NOT Is64(a[size - 1].optype) *> FOR i := size - 1 TO 0 BY -1 DO pushOp1(t, a[i]); @@ -992,7 +992,7 @@ ins.opcode := 16_58 + dest.reg[0]; writecode(t, ins); | OLoc.mem => - <* ASSERT CG_Bytes[dest.mvar.type] = 4 *> + <* ASSERT CG_Bytes[dest.mvar.mvar_type] = 4 *> build_modrm(t, dest, t.opcode[6], ins); ins.opcode := 16_FF; writecode(t, ins); @@ -1007,8 +1007,8 @@ size := SplitOperand(dest, a); BEGIN - <* ASSERT NOT a[0].optype IN Types64 *> - <* ASSERT NOT a[size - 1].optype IN Types64 *> + <* ASSERT NOT Is64(a[0].optype) *> + <* ASSERT NOT Is64(a[size - 1].optype) *> FOR i := 0 TO size - 1 DO popOp1(t, a[i]); @@ -1040,7 +1040,7 @@ <* ASSERT bits.loc = OLoc.register *> IF index.loc = OLoc.imm THEN - IF NOT TIntN.ToInt(index.imm, ins.imm) THEN + IF NOT TIntN.ToHostInteger(index.imm, ins.imm) THEN t.Err("bitOp: unable to convert immediate to INTEGER:" & TIntN.ToDiagnosticText(index.imm)); <* ASSERT FALSE *> END; @@ -1083,7 +1083,7 @@ ins.opcode := isDec * 8 + 16_40 + op.reg[0]; writecode(t, ins); ELSE - <* ASSERT op.loc = OLoc.mem AND CG_Bytes[op.mvar.type] = 4 *> + <* ASSERT op.loc = OLoc.mem AND CG_Bytes[op.mvar.mvar_type] = 4 *> build_modrm(t, op, t.opcode[isDec], ins); ins.opcode := 16_FF; writecode(t, ins); @@ -1106,7 +1106,7 @@ BEGIN ins.opcode := opcode[op].imm32; IF dest.loc = OLoc.mem THEN - get_op_size(dest.mvar.type, ins); + get_op_size(dest.mvar.mvar_type, ins); ELSE <* ASSERT dest.loc = OLoc.register *> INC(ins.opcode); @@ -1140,8 +1140,8 @@ <* ASSERT FALSE *> END ELSE - <* ASSERT NOT destA[0].optype IN Types64 *> - <* ASSERT NOT destA[destSize - 1].optype IN Types64 *> + <* ASSERT NOT Is64(destA[0].optype) *> + <* ASSERT NOT Is64(destA[destSize - 1].optype) *> FOR i := 0 TO destSize - 1 DO unOp1(t, op, destA[i]); @@ -1153,7 +1153,7 @@ VAR ins: Instruction; BEGIN <* ASSERT src.loc = OLoc.register OR (src.loc = OLoc.mem AND - CG_Bytes[src.mvar.type] = 4) *> + CG_Bytes[src.mvar.mvar_type] = 4) *> build_modrm(t, src, t.opcode[4], ins); Mn(t, "MUL EAX"); MnOp(t, src); ins.opcode := 16_F7; @@ -1167,12 +1167,12 @@ VAR ins: Instruction; BEGIN <* ASSERT dest.loc = OLoc.register *> - <* ASSERT src.loc # OLoc.mem OR CG_Bytes[src.mvar.type] = 4 *> + <* ASSERT src.loc # OLoc.mem OR CG_Bytes[src.mvar.mvar_type] = 4 *> Mn(t, "IMUL"); MnOp(t, dest); MnOp(t, src); IF src.loc = OLoc.imm THEN build_modrm(t, t.reg[dest.reg[0]], dest, ins); ins.opcode := 16_69; - IF NOT TIntN.ToInt(src.imm, ins.imm) THEN + IF NOT TIntN.ToHostInteger(src.imm, ins.imm) THEN t.Err("imulOp: unable to convert immediate to INTEGER:" & TIntN.ToDiagnosticText(src.imm)); END; ins.imsize := 4; @@ -1193,7 +1193,7 @@ VAR ins: Instruction; BEGIN <* ASSERT dest.loc = OLoc.register *> - <* ASSERT src.loc # OLoc.mem OR CG_Bytes[src.mvar.type] = 4 *> + <* ASSERT src.loc # OLoc.mem OR CG_Bytes[src.mvar.mvar_type] = 4 *> build_modrm(t, src, dest, ins); Mn(t, "IMUL"); MnOp(t, dest); MnOp(t, src); MnImmInt(t, imm); IF imsize = 1 THEN @@ -1213,7 +1213,7 @@ VAR ins: Instruction; BEGIN <* ASSERT divisor.loc = OLoc.register OR (divisor.loc = OLoc.mem - AND CG_Bytes[divisor.mvar.type] = 4) *> + AND CG_Bytes[divisor.mvar.mvar_type] = 4) *> build_modrm(t, divisor, t.opcode[6], ins); Mn(t, "DIV EAX"); MnOp(t, divisor); ins.opcode := 16_F7; @@ -1227,7 +1227,7 @@ VAR ins: Instruction; BEGIN <* ASSERT divisor.loc = OLoc.register OR (divisor.loc = OLoc.mem - AND CG_Bytes[divisor.mvar.type] = 4) *> + AND CG_Bytes[divisor.mvar.mvar_type] = 4) *> build_modrm(t, divisor, t.opcode[7], ins); Mn(t, "IDIV EAX"); MnOp(t, divisor); ins.opcode := 16_F7; @@ -1337,10 +1337,10 @@ <* ASSERT mem.loc = OLoc.mem *> - <* ASSERT CG_Bytes[mem.mvar.type] # 1 OR reg.opcode OR + <* ASSERT CG_Bytes[mem.mvar.mvar_type] # 1 OR reg.opcode OR reg.reg[0] IN RegistersForByteOperations *> - offset := mem.mvar.offset; + offset := mem.mvar.mvar_offset; IF mem.mvar.var.loc = VLoc.temp THEN <* ASSERT mem.mvar.var.parent = t.current_proc *> INC(offset, mem.mvar.var.offset); @@ -1573,7 +1573,7 @@ ins.opcode := 16_88; IF val.loc = OLoc.imm THEN ins.opcode := 16_C6; - IF NOT TIntN.ToInt(val.imm, ins.imm) THEN + IF NOT TIntN.ToHostInteger(val.imm, ins.imm) THEN t.Err("store_ind1: unable to convert immediate to INTEGER:" & TIntN.ToDiagnosticText(val.imm)); END; ins.imsize := CG_Bytes[type]; @@ -1827,12 +1827,12 @@ fstack_ensure(t, 0); (* ensure will allow an extra space for the item in memory, so height can be 0 not 1 *) Mn(t, "FLD ST"); MnMVar(t, t.ftop_mem); - IF t.ftop_mem.type = Type.Reel THEN + IF t.ftop_mem.mvar_type = Type.Reel THEN ins.opcode := fopcode[FOp.fLD].m32; ELSE ins.opcode := fopcode[FOp.fLD].m64; END; - build_modrm(t, Operand {loc := OLoc.mem, mvar := t.ftop_mem, optype := t.ftop_mem.type}, + build_modrm(t, Operand {loc := OLoc.mem, mvar := t.ftop_mem, optype := t.ftop_mem.mvar_type}, t.opcode[fopcode[FOp.fLD].memop], ins); writecode(t, ins); log_global_var(t, t.ftop_mem, -4); @@ -1898,12 +1898,12 @@ fstack_loadtop(t); END; Mn(t, "FSTP ST"); MnMVar(t, mvar); - IF mvar.type = Type.Reel THEN + IF mvar.mvar_type = Type.Reel THEN ins.opcode := fopcode[FOp.fSTP].m32; ELSE ins.opcode := fopcode[FOp.fSTP].m64; END; - build_modrm(t, Operand {loc := OLoc.mem, mvar:= mvar, optype := t.ftop_mem.type}, + build_modrm(t, Operand {loc := OLoc.mem, mvar:= mvar, optype := t.ftop_mem.mvar_type}, t.opcode[fopcode[FOp.fSTP].memop], ins); writecode(t, ins); log_global_var(t, mvar, -4); @@ -1958,8 +1958,8 @@ t.ftop_inmem := TRUE; WITH mvar = t.ftop_mem DO mvar.var := t.flitvar; - mvar.type := type; - mvar.offset := 0; + mvar.mvar_type := type; + mvar.mvar_offset := 0; END; INC(t.fstacksize); @@ -2049,9 +2049,9 @@ BEGIN IF t.debug THEN MnVar (t, mvar.var); - IF mvar.offset # 0 THEN Mn(t, "+", Fmt.Int(mvar.offset)); END; - IF (mvar.type # Type.Int32) AND (mvar.type # Type.Word32) THEN - Mn (t, ":", Target.TypeNames[mvar.type]); + IF mvar.mvar_offset # 0 THEN Mn(t, "+", Fmt.Int(mvar.mvar_offset)); END; + IF (mvar.mvar_type # Type.Int32) AND (mvar.mvar_type # Type.Word32) THEN + Mn (t, ":", Target.TypeNames[mvar.mvar_type]); END; END; END MnMVar; @@ -2096,7 +2096,7 @@ END; END MnProc; -PROCEDURE MnImmTInt(t: T; READONLY imm: TIntN.T) = +PROCEDURE MnImmTInt(t: T; READONLY imm: Target.IntN) = BEGIN IF t.debug THEN Mn(t, " $", TIntN.ToText (imm)); @@ -2205,11 +2205,11 @@ patch_loc := t.obj.cursor(Seg.Text) + reltocurs; IF mvar.var = t.flitvar THEN <* ASSERT t.f_litlist # NIL AND t.f_litlist.loc = 0 *> - <* ASSERT t.f_litlist.flit_size = CG_Bytes[mvar.type] *> - <* ASSERT mvar.type = Type.Reel OR mvar.type = Type.LReel OR mvar.type = Type.XReel *> + <* ASSERT t.f_litlist.flit_size = CG_Bytes[mvar.mvar_type] *> + <* ASSERT mvar.mvar_type = Type.Reel OR mvar.mvar_type = Type.LReel OR mvar.mvar_type = Type.XReel *> t.f_litlist.loc := patch_loc; ELSE - t.obj.patch(Seg.Text, patch_loc, mvar.offset + mvar.var.offset, 4); + t.obj.patch(Seg.Text, patch_loc, mvar.mvar_offset + mvar.var.offset, 4); t.obj.relocate(t.textsym, patch_loc, mvar.var.symbol); END END log_global_var; Index: M3x86.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/M3x86.m3,v retrieving revision 1.147 diff -u -r1.147 M3x86.m3 --- M3x86.m3 27 Feb 2010 12:16:09 -0000 1.147 +++ M3x86.m3 27 Feb 2010 12:33:14 -0000 @@ -8,7 +8,7 @@ MODULE M3x86 EXPORTS M3x86, M3x86Rep; IMPORT Wr, Text, Fmt, IntRefTbl, Word; -IMPORT M3CG, M3ID, M3CG_Ops, Target, TInt AS TargetInt, TFloat AS TargetFloat; +IMPORT M3CG, M3ID, M3CG_Ops, Target, TFloat; IMPORT TIntN, TWordN; IMPORT M3ObjFile, TargetMap; @@ -51,7 +51,7 @@ init_varstore : x86Var := NIL; init_count : INTEGER; - (* What determines the sizes here? Historically it was [0..1]. *) + (* What determines the sizes here? Historically it was 2. *) call_param_size := ARRAY [0 .. 9] OF INTEGER { 0, .. }; in_proc_call : [0 .. 10] := 0; static_link := ARRAY [0 .. 9] OF x86Var { NIL, .. }; @@ -500,8 +500,8 @@ u.wr.Cmd ("declare_subrange"); u.wr.Tipe (t); u.wr.Tipe (domain); - u.wr.TInt (min); - u.wr.TInt (max); + u.wr.TInt (TIntN.FromTargetInt(min, NUMBER(min))); + u.wr.TInt (TIntN.FromTargetInt(min, NUMBER(max))); u.wr.BInt (s); u.wr.NL (); END @@ -683,8 +683,8 @@ PROCEDURE NewVar (u: U; t: Type; uid: TypeUID; s: ByteSize; a: Alignment; name: Name := M3ID.NoID): x86Var = - VAR v := NEW (x86Var, tag := u.next_var, type := t, size := s, - align := a, seg := Seg.Data); + VAR v := NEW (x86Var, tag := u.next_var, var_type := t, var_size := s, + var_align := a, seg := Seg.Data); BEGIN IF name = M3ID.NoID THEN v.name := M3ID.Add("T$" & Fmt.Int(v.tag)); @@ -751,9 +751,9 @@ BEGIN <* ASSERT inited *> - realvar.type := t; - realvar.size := s; - realvar.align := a; + realvar.var_type := t; + realvar.var_size := s; + realvar.var_align := a; IF exported THEN u.obj.export_symbol(realvar.symbol); @@ -792,9 +792,10 @@ BEGIN v.loc := VLoc.global; v.seg := SegMap [is_const]; - IF inited - THEN v.symbol := u.obj.define_symbol (v.name, v.seg, 0); - ELSE v.symbol := u.obj.define_bss_symbol (v.name, s, a); + IF inited THEN + v.symbol := u.obj.define_symbol (v.name, v.seg, 0); + ELSE + v.symbol := u.obj.define_bss_symbol (v.name, s, a); END; IF exported THEN u.obj.export_symbol (v.symbol); @@ -819,9 +820,10 @@ f: Frequency): Var = VAR v: x86Var; BEGIN - IF u.in_proc - THEN v := get_temp_var (u, t, s, a, n); - ELSE v := create_temp_var (u, t, s, a, n); + IF u.in_proc THEN + v := get_temp_var (u, t, s, a, n); + ELSE + v := create_temp_var (u, t, s, a, n); END; IF u.debug THEN @@ -857,9 +859,10 @@ END; END; - IF std_call - THEN RETURN M3ID.Add(Fmt.F ("_%s@%s", txt, Fmt.Int (arg_size))); - ELSE RETURN M3ID.Add(Fmt.F ("_%s", txt)); + IF std_call THEN + RETURN M3ID.Add(Fmt.F ("_%s@%s", txt, Fmt.Int (arg_size))); + ELSE + RETURN M3ID.Add(Fmt.F ("_%s", txt)); END; END mangle_procname; @@ -891,8 +894,7 @@ IF u.param_proc.import THEN u.param_proc.symbol := u.obj.import_symbol(u.param_proc.name); ELSE - u.param_proc.symbol := u.obj.define_symbol(u.param_proc.name, - Seg.Text, 0); + u.param_proc.symbol := u.obj.define_symbol(u.param_proc.name, Seg.Text, 0); END; IF u.param_proc.exported THEN @@ -918,8 +920,7 @@ RETURN v; END declare_param; -PROCEDURE declare_temp (u: U; s: ByteSize; a: Alignment; t: Type; - in_memory:BOOLEAN): Var = +PROCEDURE declare_temp (u: U; s: ByteSize; a: Alignment; t: Type; in_memory:BOOLEAN): Var = VAR v: x86Var; BEGIN <* ASSERT u.in_proc *> @@ -958,12 +959,12 @@ FOR i := 0 TO u.current_proc.tempsize - 1 DO WITH temp = u.current_proc.temparr[i] DO - IF temp.free AND temp.var.size = s AND temp.var.align >= a THEN + IF temp.free AND temp.var.var_size = s AND temp.var.var_align >= a THEN (* reinitialize existing temporary variable *) temp.free := FALSE; - temp.var.type := t; + temp.var.var_type := t; temp.var.stack_temp := FALSE; temp.var.scope := u.next_scope - 1; RETURN temp.var; @@ -981,7 +982,7 @@ WITH temp = u.current_proc.temparr[u.current_proc.tempsize] DO temp.var := create_temp_var(u, t, s, a, n); - <* ASSERT temp.var.type = t *> + <* ASSERT temp.var.var_type = t *> temp.free := FALSE; temp.var.scope := u.next_scope - 1; END; @@ -1056,8 +1057,8 @@ offs := u.obj.cursor(realvar.seg); - IF Word.And(offs, realvar.align - 1) # 0 THEN - pad := realvar.align - Word.And(offs, realvar.align - 1); + IF Word.And(offs, realvar.var_align - 1) # 0 THEN + pad := realvar.var_align - Word.And(offs, realvar.var_align - 1); INC(offs, pad); IF Word.And(pad, 3) # 0 THEN u.obj.append(realvar.seg, 0, Word.And(pad, 3)); @@ -1086,29 +1087,24 @@ <* ASSERT v = u.init_varstore *> - pad_init(u, realvar.size); + pad_init(u, realvar.var_size); u.init_varstore := NIL; END end_init; -PROCEDURE init_int (u: U; o: ByteOffset; READONLY value: Target.Int; - t: Type) = - VAR int: INTEGER; +PROCEDURE init_int (u: U; o: ByteOffset; READONLY value: Target.Int; t: Type) = BEGIN IF u.debug THEN u.wr.Cmd ("init_int"); u.wr.Int (o); - u.wr.TInt (value); + u.wr.TInt (TIntN.FromTargetInt(value, CG_Bytes[t])); u.wr.TName (t); u.wr.NL (); END; pad_init(u, o); - - IF NOT TargetInt.ToInt(value, int) THEN - u.Err("Failed to convert target integer in init_int"); - END; - u.obj.append(u.init_varstore.seg, int, CG_Bytes[t]); + u.obj.appendBytes(u.init_varstore.seg, SUBARRAY(value, 0, CG_Bytes[t])); INC(u.init_count, CG_Bytes[t]); + END init_int; PROCEDURE init_proc (u: U; o: ByteOffset; value: Proc) = @@ -1215,7 +1211,7 @@ u.wr.NL (); END; - size := TargetFloat.ToBytes(f, flarr); + size := TFloat.ToBytes(f, flarr); <* ASSERT size = 4 OR size = 8 *> @@ -1230,7 +1226,7 @@ PROCEDURE pad_init (u: U; o: ByteOffset) = BEGIN <* ASSERT u.init_count <= o *> - <* ASSERT o <= u.init_varstore.size *> + <* ASSERT o <= u.init_varstore.var_size *> FOR i := u.init_count TO o - 1 DO u.obj.append(u.init_varstore.seg, 0, 1); @@ -1244,11 +1240,12 @@ PROCEDURE NewProc (u: U; n: Name; n_params: INTEGER; ret_type: Type; cc: CallingConvention): x86Proc = VAR p := NEW (x86Proc, tag := u.next_proc, n_params := n_params, - type := ret_type, stdcall := (cc.m3cg_id = 1)); + proc_type := ret_type, stdcall := (cc.m3cg_id = 1)); BEGIN - IF n = M3ID.NoID - THEN p.name := M3ID.Add("P$" & Fmt.Int(p.tag)); - ELSE p.name := n; + IF n = M3ID.NoID THEN + p.name := M3ID.Add("P$" & Fmt.Int(p.tag)); + ELSE + p.name := n; END; p.templimit := 16; @@ -1365,7 +1362,7 @@ u.cg.pushOp(u.cg.reg[EBP]); u.cg.movOp(u.cg.reg[EBP], u.cg.reg[ESP]); - u.cg.immOp(Op.oSUB, u.cg.reg[ESP], TWordN.Max16); + u.cg.immOp(Op.oSUB, u.cg.reg[ESP], Target.Word16.maxN); u.procframe_ptr := u.obj.cursor(Seg.Text) - 4; u.cg.pushOp(u.cg.reg[EBX]); @@ -1455,93 +1452,105 @@ (*------------------------------------------------------------ statements ---*) -PROCEDURE set_label (u: U; l: Label; <*UNUSED*> barrier: BOOLEAN) = - (* define 'l' to be at the current pc *) +PROCEDURE debug_set_label (u: U; label: Label) = BEGIN IF u.debug THEN - u.wr.OutT ("."); - u.wr.Lab (l); + u.wr.OutT ("set_label"); + u.wr.Lab (label); u.wr.NL (); END; + END debug_set_label; - u.cg.set_label(l); +PROCEDURE set_label (u: U; label: Label; <*UNUSED*> barrier: BOOLEAN) = + (* define 'label' to be at the current pc *) + BEGIN + debug_set_label(u, label); + + u.cg.set_label(label); u.vstack.clearall(); END set_label; -PROCEDURE jump (u: U; l: Label) = - (* GOTO l *) +PROCEDURE jump (u: U; label: Label) = + (* GOTO label *) BEGIN IF u.debug THEN u.wr.Cmd ("jump"); - u.wr.Lab (l); + u.wr.Lab (label); u.wr.NL (); END; - u.cg.brOp(Cond.Always, l); + u.cg.brOp(Cond.Always, label); END jump; -PROCEDURE if_true (u: U; t: IType; l: Label; <*UNUSED*> f: Frequency) = - (* IF (s0.t # 0) GOTO l ; pop *) +PROCEDURE if_true (u: U; t: IType; label: Label; <*UNUSED*> f: Frequency) = + (* IF (s0.t # 0) GOTO label ; pop *) BEGIN IF u.debug THEN u.wr.Cmd ("if_true"); u.wr.TName (t); - u.wr.Lab (l); + u.wr.Lab (label); u.wr.NL (); END; u.vstack.doimm (Op.oCMP, TZero, FALSE); - u.cg.brOp (Cond.NZ, l); + u.cg.brOp (Cond.NZ, label); END if_true; -PROCEDURE if_false (u: U; t: IType; l: Label; <*UNUSED*> f: Frequency) = - (* IF (s0.t = 0) GOTO l ; pop *) +PROCEDURE if_false (u: U; t: IType; label: Label; <*UNUSED*> f: Frequency) = + (* IF (s0.t = 0) GOTO label ; pop *) BEGIN IF u.debug THEN u.wr.Cmd ("if_false"); u.wr.TName (t); - u.wr.Lab (l); + u.wr.Lab (label); u.wr.NL (); END; u.vstack.doimm (Op.oCMP, TZero, FALSE); - u.cg.brOp (Cond.Z, l); + u.cg.brOp (Cond.Z, label); END if_false; -PROCEDURE if_compare (u: U; t: ZType; op: CompareOp; l: Label; +PROCEDURE if_compare (u: U; t: ZType; op: CompareOp; label: Label; <*UNUSED*> f: Frequency) = - (* IF (s1.t op s0.t) GOTO l ; pop(2) *) + (* IF (s1.t op s0.t) GOTO label ; pop(2) *) VAR cond := CompareOpCond [op]; BEGIN IF u.debug THEN u.wr.Cmd ("if_compare"); u.wr.TName (t); u.wr.OutT (CompareOpName [op]); - u.wr.Lab (l); + u.wr.Lab (label); u.wr.NL (); END; CASE t OF - | Type.Int32, Type.Int64 => - IF u.vstack.dobin(Op.oCMP, TRUE, FALSE, t) THEN cond := revcond[cond]; END; - | Type.Word32, Type.Word64, Type.Addr => - IF u.vstack.dobin(Op.oCMP, TRUE, FALSE, t) THEN cond := revcond[cond]; END; - cond := unscond[cond]; + | Type.Word32, Type.Int32, Type.Word64, Type.Int64, Type.Addr => + IF u.vstack.dobin(Op.oCMP, TRUE, FALSE, t) THEN + cond := revcond[cond]; + END; | Type.Reel, Type.LReel, Type.XReel => - IF u.cg.ftop_inmem - THEN u.cg.binFOp (FOp.fCOMP, 1); - ELSE u.cg.binFOp (FOp.fCOMPP, 1); cond := revcond[cond]; + IF u.cg.ftop_inmem THEN + u.cg.binFOp (FOp.fCOMP, 1); + ELSE + u.cg.binFOp (FOp.fCOMPP, 1); + cond := revcond[cond]; END; u.vstack.discard (2); u.vstack.unlock (); u.vstack.corrupt (EAX, operandPart := 0); u.cg.noargFOp (FOp.fNSTSWAX); u.cg.noargOp (Op.oSAHF); - cond := unscond[cond]; (* FCOM sets the unsigned compare flags *) END; - u.cg.brOp(cond, l); + CASE t OF + | Type.Word32, Type.Word64, Type.Addr, + Type.Reel, Type.LReel, Type.XReel => (* FCOM sets the unsigned compare flags *) + cond := unscond[cond]; + ELSE + END; + + u.cg.brOp(cond, label); END if_compare; PROCEDURE case_jump (u: U; t: IType; READONLY labels: ARRAY OF Label) = @@ -1576,10 +1585,9 @@ u.vstack.unlock(); WITH stack0 = u.vstack.pos(0, "exit_proc") DO - CASE t OF - | Type.Reel, Type.LReel, Type.XReel => + IF Target.FloatType[t] THEN u.cg.f_exitproc(); - | Type.Int64, Type.Word64 => + ELSIF Is64(t) THEN u.vstack.find(stack0, Force.regset, RegSet { EAX, EDX }); ELSE u.vstack.find(stack0, Force.regset, RegSet { EAX }); @@ -1656,7 +1664,7 @@ u.wr.NL (); END; - u.vstack.push(MVar {var := v, offset := o, type := t}); + u.vstack.push(MVar {var := v, mvar_offset := o, mvar_type := t}); END load; PROCEDURE store (u: U; v: Var; o: ByteOffset; z: ZType; t: MType; ) = @@ -1671,7 +1679,7 @@ u.wr.NL (); END; - u.vstack.pop(MVar {var := v, offset := o, type := t}); + u.vstack.pop(MVar {var := v, mvar_offset := o, mvar_type := t}); END store; PROCEDURE load_address (u: U; v: Var; o: ByteOffset) = @@ -1689,7 +1697,8 @@ PROCEDURE load_indirect (u: U; o: ByteOffset; t: MType; z: ZType) = (* s0.z := Mem [s0.A + o].t *) - VAR newreg, newreg1: Regno; + VAR newreg: ARRAY OperandPart OF Regno; + size: OperandSize; BEGIN IF u.debug THEN u.wr.Cmd ("load_indirect"); @@ -1700,32 +1709,46 @@ END; u.vstack.unlock(); + WITH stack0 = u.vstack.pos(0, "load_indirect") DO u.vstack.find(stack0, Force.anyreg, RegSet {}, TRUE); - CASE t OF - | Type.Reel, Type.LReel, Type.XReel => + IF Target.FloatType [t] THEN u.cg.f_loadind(u.vstack.op(stack0), o, t); u.vstack.dealloc_reg(stack0, operandPart := 0); u.vstack.set_fstack(stack0); - | Type.Int64, Type.Word64 => - newreg := u.vstack.freereg(operandPart := 0); - newreg1 := u.vstack.freereg(AllRegisters - RegSet{newreg}, - operandPart := 1); - u.cg.load_ind(newreg, u.vstack.op(stack0), o, t); - u.cg.load_ind(newreg1, u.vstack.op(stack0), o + 4, t); - u.vstack.dealloc_reg(stack0, operandPart := 0); - u.vstack.set_reg(stack0, newreg, operandPart := 0); - u.vstack.set_reg(stack0, newreg1, operandPart := 1); ELSE - IF CG_Bytes[t] = 1 THEN - newreg := u.vstack.freereg(RegSet { EAX, EBX, ECX, EDX }, - operandPart := 0); - ELSE - newreg := u.vstack.freereg(operandPart := 0); + size := GetTypeSize(t); + <* ASSERT size = GetTypeSize(z) *> + + (* allocate the registers *) + + FOR i := 0 TO size - 1 DO + IF CG_Bytes[t] = 1 THEN + <* ASSERT i = 0 AND size = 1 *> + newreg[i] := u.vstack.freereg(RegistersForByteOperations, operandPart := i); + ELSE + IF i = 0 THEN + newreg[i] := u.vstack.freereg(operandPart := i); + ELSE + newreg[i] := u.vstack.freereg(AllRegisters - RegSet{newreg[0]}, operandPart := i); + END; + END; + <* ASSERT newreg[i] # -1 *> END; - u.cg.load_ind(newreg, u.vstack.op(stack0), o, t); + + (* do the loads *) + + FOR i := 0 TO size - 1 DO + u.cg.load_ind(newreg[i], u.vstack.op(stack0), o + 4 * i, t); + END; + + (* do the bookkeeping about the loads *) + (* previous contents of stack0 was just an address, no loop over size *) + u.vstack.dealloc_reg(stack0, operandPart := 0); - u.vstack.set_reg(stack0, newreg, operandPart := 0); + FOR i := 0 TO size - 1 DO + u.vstack.set_reg(stack0, newreg[i], operandPart := i); + END; END; u.vstack.set_type(stack0, z); END @@ -1769,9 +1792,9 @@ u.vstack.pushimmT(TZero, Type.Addr); END load_nil; -PROCEDURE load_integer (u: U; t: IType; READONLY i: Target.Int) = +PROCEDURE load_integer (u: U; t: IType; READONLY j: Target.Int) = (* push ; s0.t := i *) - VAR int: TIntN.T; + VAR i := TIntN.FromTargetInt(j, CG_Bytes[t]); BEGIN IF u.debug THEN u.wr.Cmd ("load_integer"); @@ -1780,11 +1803,8 @@ u.wr.NL (); END; - IF NOT TIntN.FromTInt(i, CG_Bytes[t], int) THEN - u.Err("Failed to convert target integer in load_integer"); - END; u.vstack.unlock(); - u.vstack.pushimmT(int, t); + u.vstack.pushimmT(i, t); END load_integer; PROCEDURE load_float (u: U; t: RType; READONLY f: Target.Float) = @@ -1800,7 +1820,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; @@ -1866,20 +1886,20 @@ u.wr.NL (); END; - CASE t OF - | Type.Reel, Type.LReel, Type.XReel => + IF Is64(t) THEN + start_int_proc (u, Builtin.mul64); + pop_param(u, Type.Word64); + pop_param(u, Type.Word64); + call_64 (u, Builtin.mul64); + ELSIF Target.FloatType [t] THEN u.cg.binFOp(FOp.fMUL, 1); u.vstack.discard(1); - | Type.Int32 => + ELSIF t = Type.Int32 THEN u.vstack.doimul(); - | Type.Word32 => + ELSE + <* ASSERT t = Type.Word32 *> u.vstack.doumul(); - | Type.Int64, Type.Word64 => - start_int_proc (u, Builtin.mul64); - pop_param(u, t); - pop_param(u, t); - call_64 (u, Builtin.mul64); - END; + END END multiply; PROCEDURE divide (u: U; t: RType) = @@ -1899,6 +1919,7 @@ PROCEDURE div (u: U; t: IType; a, b: Sign) = (* s1.t := s1.t DIV s0.t ; pop *) + VAR builtin: Builtin; BEGIN IF u.debug THEN u.wr.Cmd ("div"); @@ -1908,30 +1929,30 @@ u.wr.NL (); END; - CASE t OF - | Type.Int32 => - u.vstack.dodiv(a, b); - | Type.Word32 => + IF Is64(t) THEN + CASE t OF Type.Int64 => builtin := Builtin.div64; + | Type.Word64 => builtin := Builtin.udiv64; + ELSE <* ASSERT FALSE *> + END; + u.vstack.swap(); + start_int_proc (u, builtin); + pop_param(u, Type.Word64); + pop_param(u, Type.Word64); + call_64 (u, builtin); + RETURN; + END; + + IF IsWord(t) THEN a := Sign.Positive; b := Sign.Positive; - u.vstack.dodiv(a, b); - | Type.Int64 => - u.vstack.swap(); - start_int_proc (u, Builtin.div64); - pop_param(u, t); - pop_param(u, t); - call_64 (u, Builtin.div64); - | Type.Word64 => - u.vstack.swap(); - start_int_proc (u, Builtin.udiv64); - pop_param(u, t); - pop_param(u, t); - call_64 (u, Builtin.udiv64); END; + + u.vstack.dodiv(a, b); END div; PROCEDURE mod (u: U; t: IType; a, b: Sign) = (* s1.t := s1.t MOD s0.t ; pop *) + VAR builtin: Builtin; BEGIN IF u.debug THEN u.wr.Cmd ("mod"); @@ -1941,26 +1962,25 @@ u.wr.NL (); END; - CASE t OF - | Type.Int32 => - u.vstack.domod(a, b); - | Type.Word32 => + IF Is64(t) THEN + CASE t OF Type.Int64 => builtin := Builtin.mod64; + | Type.Word64 => builtin := Builtin.umod64; + ELSE <* ASSERT FALSE *> + END; + u.vstack.swap(); + start_int_proc (u, builtin); + pop_param(u, Type.Word64); + pop_param(u, Type.Word64); + call_64 (u, builtin); + RETURN; + END; + + IF IsWord(t) THEN a := Sign.Positive; b := Sign.Positive; - u.vstack.domod(a, b); - | Type.Int64 => - u.vstack.swap(); - start_int_proc (u, Builtin.mod64); - pop_param(u, t); - pop_param(u, t); - call_64 (u, Builtin.mod64); - | Type.Word64 => - u.vstack.swap(); - start_int_proc (u, Builtin.umod64); - pop_param(u, t); - pop_param(u, t); - call_64 (u, Builtin.umod64); END; + + u.vstack.domod(a, b); END mod; PROCEDURE negate (u: U; t: AType) = @@ -1988,10 +2008,11 @@ u.wr.NL (); END; - CASE t OF - | Type.Word32, Type.Word64 => (* no-op *) - | Type.Int32, Type.Int64 => u.vstack.doabs(); - | Type.Reel, Type.LReel, Type.XReel => + IF IsWord(t) THEN + RETURN; + ELSIF IsInt(t) THEN + u.vstack.doabs(); + ELSE u.cg.noargFOp(FOp.fABS); END END abs; @@ -2053,80 +2074,47 @@ (*------------------------------------------------------------------ sets ---*) -PROCEDURE set_union (u: U; s: ByteSize) = - (* s2.B := s1.B + s0.B ; pop(3) *) +PROCEDURE set_op3(u: U; s: ByteSize; builtin: Builtin) = + (* s2.B := s1.B op s0.B ; pop(3) *) BEGIN IF u.debug THEN - u.wr.Cmd ("set_union"); + u.wr.Cmd (BuiltinDesc[builtin].name); u.wr.Int (s); u.wr.NL (); END; - start_int_proc (u, Builtin.set_union); + start_int_proc (u, builtin); load_stack_param (u, Type.Addr, 2); load_stack_param (u, Type.Addr, 1); load_stack_param (u, Type.Addr, 0); u.vstack.discard (3); u.vstack.pushimmI (s * 8, Type.Word32); pop_param (u, Type.Word32); - call_int_proc (u, Builtin.set_union); + call_int_proc (u, builtin); + END set_op3; + +PROCEDURE set_union (u: U; s: ByteSize) = + (* s2.B := s1.B + s0.B ; pop(3) *) + BEGIN + set_op3(u, s, Builtin.set_union); END set_union; PROCEDURE set_difference (u: U; s: ByteSize) = (* s2.B := s1.B - s0.B ; pop(3) *) BEGIN - IF u.debug THEN - u.wr.Cmd ("set_difference"); - u.wr.Int (s); - u.wr.NL (); - END; - - start_int_proc (u, Builtin.set_difference); - load_stack_param (u, Type.Addr, 2); - load_stack_param (u, Type.Addr, 1); - load_stack_param (u, Type.Addr, 0); - u.vstack.discard (3); - u.vstack.pushimmI (s * 8, Type.Word32); - pop_param (u, Type.Word32); - call_int_proc (u, Builtin.set_difference); + set_op3(u, s, Builtin.set_difference); END set_difference; PROCEDURE set_intersection (u: U; s: ByteSize) = (* s2.B := s1.B * s0.B ; pop(3) *) BEGIN - IF u.debug THEN - u.wr.Cmd ("set_intersection"); - u.wr.Int (s); - u.wr.NL (); - END; - - start_int_proc (u, Builtin.set_intersection); - load_stack_param (u, Type.Addr, 2); - load_stack_param (u, Type.Addr, 1); - load_stack_param (u, Type.Addr, 0); - u.vstack.discard (3); - u.vstack.pushimmI (s * 8, Type.Word32); - pop_param (u, Type.Word32); - call_int_proc (u, Builtin.set_intersection); + set_op3(u, s, Builtin.set_intersection); END set_intersection; PROCEDURE set_sym_difference (u: U; s: ByteSize) = (* s2.B := s1.B / s0.B ; pop(3) *) BEGIN - IF u.debug THEN - u.wr.Cmd ("set_sym_difference"); - u.wr.Int (s); - u.wr.NL (); - END; - - start_int_proc (u, Builtin.set_sym_difference); - load_stack_param (u, Type.Addr, 2); - load_stack_param (u, Type.Addr, 1); - load_stack_param (u, Type.Addr, 0); - u.vstack.discard (3); - u.vstack.pushimmI (s * 8, Type.Word32); - pop_param (u, Type.Word32); - call_int_proc (u, Builtin.set_sym_difference); + set_op3(u, s, Builtin.set_sym_difference); END set_sym_difference; PROCEDURE set_member (u: U; s: ByteSize; t: IType) = @@ -2282,7 +2270,7 @@ PROCEDURE not (u: U; t: IType) = (* s0.t := Word.Not (s0.t) *) - VAR not: TIntN.T; + VAR not: Target.IntN; BEGIN IF u.debug THEN u.wr.Cmd ("not"); @@ -2348,20 +2336,17 @@ u.wr.NL (); END; - CASE t OF - | Type.Int32, Type.Word32 => - IF NOT u.vstack.doshift (t) THEN - do_rotate_or_shift_64 (u, Builtin.shift64); - END; - | Type.Int64, Type.Word64 => - do_rotate_or_shift_64 (u, Builtin.shift64); + IF (NOT Is64(t)) AND u.vstack.doshift (t) THEN + RETURN; END; + + do_rotate_or_shift_64 (u, Builtin.shift64); END shift; PROCEDURE shift_left (u: U; t: IType) = (* s1.t := Word.Shift (s1.t, s0.t) ; pop *) - VAR shiftResult: TIntN.T; - and: TIntN.T; + VAR shiftResult: Target.IntN; + and: Target.IntN; shiftCount: INTEGER; BEGIN IF u.debug THEN @@ -2375,7 +2360,7 @@ stack1 = u.vstack.pos(1, "shift_left") DO IF u.vstack.loc(stack0) = OLoc.imm THEN IF u.vstack.loc(stack1) = OLoc.imm THEN - IF NOT TIntN.ToInt(u.vstack.op(stack0).imm, shiftCount) THEN + IF NOT TIntN.ToHostInteger(u.vstack.op(stack0).imm, shiftCount) THEN u.Err("unable to convert shift count to host integer"); END; @@ -2399,10 +2384,7 @@ (* shift non-constant *) - CASE t OF - | Type.Int32, Type.Word32 => - (* continue *) - | Type.Int64, Type.Word64 => + IF Is64(t) THEN do_custom_calling_convention_shift_64 (u, Builtin.shift_left_64); RETURN; END; @@ -2425,8 +2407,8 @@ PROCEDURE shift_right (u: U; t: IType) = (* s1.t := Word.Shift (s1.t, -s0.t) ; pop *) VAR shiftCount: INTEGER; - shift: TIntN.T; - and: TIntN.T; + shift: Target.IntN; + and: Target.IntN; BEGIN IF u.debug THEN u.wr.Cmd ("shift_right"); @@ -2442,7 +2424,7 @@ (* shift constant by a constant *) - IF NOT TIntN.ToInt(u.vstack.op(stack0).imm, shiftCount) THEN + IF NOT TIntN.ToHostInteger(u.vstack.op(stack0).imm, shiftCount) THEN u.Err("unable to convert shift count to host integer"); END; TWordN.Shift(u.vstack.op(stack1).imm, -shiftCount, shift); @@ -2464,10 +2446,7 @@ (* shift a non-constant or non-zero *) IF ((u.vstack.loc(stack1) # OLoc.imm) OR (TIntN.NE(u.vstack.op(stack1).imm, TZero))) THEN - CASE t OF - | Type.Int32, Type.Word32 => - (* continue *) - | Type.Int64, Type.Word64 => + IF Is64(t) THEN do_custom_calling_convention_shift_64 (u, Builtin.shift_right_64); RETURN; END; @@ -2496,16 +2475,18 @@ u.wr.NL (); END; - IF NOT u.vstack.dorotate(t) THEN - do_rotate_or_shift_64 (u, Builtin.rotate64); + IF u.vstack.dorotate(t) THEN + RETURN; END; + + do_rotate_or_shift_64 (u, Builtin.rotate64); END rotate; PROCEDURE rotate_left (u: U; t: IType) = (* s1.t := Word.Rotate (s1.t, s0.t) ; pop *) VAR rotateCount: INTEGER; - rotate: TIntN.T; - and: TIntN.T; + rotate: Target.IntN; + and: Target.IntN; BEGIN IF u.debug THEN u.wr.Cmd ("rotate_left"); @@ -2518,7 +2499,7 @@ stack1 = u.vstack.pos(1, "rotate_left") DO IF u.vstack.loc(stack0) = OLoc.imm THEN IF u.vstack.loc(stack1) = OLoc.imm THEN - IF NOT TIntN.ToInt(u.vstack.op(stack0).imm, rotateCount) THEN + IF NOT TIntN.ToHostInteger(u.vstack.op(stack0).imm, rotateCount) THEN u.Err("unable to convert rotate count to host integer"); END; TWordN.Rotate(u.vstack.op(stack1).imm, rotateCount, rotate); @@ -2526,10 +2507,7 @@ ELSE TWordN.And(u.vstack.op(stack0).imm, MaximumShift[t], and); u.vstack.set_imm(stack0, and); - CASE t OF - | Type.Int32, Type.Word32 => - (* continue *) - | Type.Int64, Type.Word64 => + IF Is64(t) THEN do_rotate_or_shift_64(u, Builtin.rotate_left64); RETURN; END; @@ -2538,10 +2516,7 @@ u.vstack.newdest(u.vstack.op(stack1)); END ELSE - CASE t OF - | Type.Int32, Type.Word32 => - (* continue *) - | Type.Int64, Type.Word64 => + IF Is64(t) THEN do_rotate_or_shift_64(u, Builtin.rotate_left64); RETURN; END; @@ -2563,8 +2538,8 @@ PROCEDURE rotate_right (u: U; t: IType) = (* s1.t := Word.Rotate (s1.t, -s0.t) ; pop *) VAR rotateCount: INTEGER; - rotate: TIntN.T; - and: TIntN.T; + rotate: Target.IntN; + and: Target.IntN; BEGIN IF u.debug THEN u.wr.Cmd ("rotate_right"); @@ -2577,7 +2552,7 @@ stack1 = u.vstack.pos(1, "rotate_right") DO IF u.vstack.loc(stack0) = OLoc.imm THEN IF u.vstack.loc(stack1) = OLoc.imm THEN - IF NOT TIntN.ToInt(u.vstack.op(stack0).imm, rotateCount) THEN + IF NOT TIntN.ToHostInteger(u.vstack.op(stack0).imm, rotateCount) THEN u.Err("unable to convert rotate count to host integer"); END; TWordN.Rotate(u.vstack.op(stack1).imm, -rotateCount, rotate); @@ -2585,10 +2560,7 @@ ELSE TWordN.And(u.vstack.op(stack0).imm, MaximumShift[t], and); u.vstack.set_imm(stack0, and); - CASE t OF - | Type.Int32, Type.Word32 => - (* continue *) - | Type.Int64, Type.Word64 => + IF Is64(t) THEN do_rotate_or_shift_64(u, Builtin.rotate_right64); RETURN; END; @@ -2597,10 +2569,7 @@ u.vstack.newdest(u.vstack.op(stack1)); END ELSE - CASE t OF - | Type.Int32, Type.Word32 => - (* continue *) - | Type.Int64, Type.Word64 => + IF Is64(t) THEN do_rotate_or_shift_64(u, Builtin.rotate_right64); RETURN; END; @@ -2640,32 +2609,30 @@ <*ASSERT FALSE*> END chop; -PROCEDURE extract (u: U; t: IType; sign: BOOLEAN) = +PROCEDURE extract (u: U; t: IType; sign_extend: BOOLEAN) = (* s2.t := Word.Extract(s2.t, s1.t, s0.t); - IF sign THEN SignExtend s2 END; pop(2) *) + IF sign_extend THEN SignExtend s2 END; pop(2) *) + VAR builtin := Builtin.extract64; BEGIN IF u.debug THEN u.wr.Cmd ("extract"); u.wr.TName (t); - u.wr.Bool (sign); + u.wr.Bool (sign_extend); u.wr.NL (); END; - IF NOT u.vstack.doextract(t, sign) THEN - IF sign THEN - start_int_proc (u, Builtin.extract_and_sign_extend64); - pop_param(u, Type.Word32); (* n *) - pop_param(u, Type.Word32); (* m *) - pop_param(u, Type.Word64); (* value *) - call_64 (u, Builtin.extract_and_sign_extend64); - ELSE - start_int_proc (u, Builtin.extract64); - pop_param(u, Type.Word32); (* n *) - pop_param(u, Type.Word32); (* m *) - pop_param(u, Type.Word64); (* value *) - call_64 (u, Builtin.extract64); - END; + IF u.vstack.doextract(t, sign_extend) THEN + RETURN; END; + + IF sign_extend THEN + builtin := Builtin.extract_and_sign_extend64; + END; + start_int_proc (u, builtin); + pop_param(u, Type.Word32); (* n *) + pop_param(u, Type.Word32); (* m *) + pop_param(u, Type.Word64); (* value *) + call_64 (u, builtin); END extract; PROCEDURE extract_n (u: U; t: IType; sign: BOOLEAN; n: INTEGER) = @@ -2680,10 +2647,12 @@ u.wr.NL (); END; - IF NOT u.vstack.doextract_n(t, sign, n) THEN - u.vstack.pushimmI(n, Type.Word32); - extract(u, t, sign); + IF u.vstack.doextract_n(t, sign, n) THEN + RETURN; END; + + u.vstack.pushimmI(n, Type.Word32); + extract(u, t, sign); END extract_n; PROCEDURE extract_mn (u: U; t: IType; sign: BOOLEAN; m, n: INTEGER) = @@ -2699,11 +2668,13 @@ u.wr.NL (); END; - IF NOT u.vstack.doextract_mn(t, sign, m, n) THEN - u.vstack.pushimmI(m, Type.Word32); - u.vstack.pushimmI(n, Type.Word32); - extract(u, t, sign); + IF u.vstack.doextract_mn(t, sign, m, n) THEN + RETURN; END; + + u.vstack.pushimmI(m, Type.Word32); + u.vstack.pushimmI(n, Type.Word32); + extract(u, t, sign); END extract_mn; PROCEDURE insert (u: U; t: IType) = @@ -2715,14 +2686,15 @@ u.wr.NL (); END; - IF NOT u.vstack.doinsert(t) THEN - start_int_proc (u, Builtin.insert64); - pop_param(u, Type.Word32); - pop_param(u, Type.Word32); - pop_param(u, Type.Word64); - pop_param(u, Type.Word64); - call_64 (u, Builtin.insert64); + IF u.vstack.doinsert(t) THEN + RETURN; END; + start_int_proc (u, Builtin.insert64); + pop_param(u, Type.Word32); + pop_param(u, Type.Word32); + pop_param(u, Type.Word64); + pop_param(u, Type.Word64); + call_64 (u, Builtin.insert64); END insert; PROCEDURE insert_n (u: U; t: IType; n: INTEGER) = @@ -2735,10 +2707,11 @@ u.wr.NL (); END; - IF NOT u.vstack.doinsert_n(t, n) THEN - u.vstack.pushimmI(n, Type.Word32); - u.insert(t); + IF u.vstack.doinsert_n(t, n) THEN + RETURN; END; + u.vstack.pushimmI(n, Type.Word32); + u.insert(t); END insert_n; PROCEDURE insert_mn (u: U; t: IType; m, n: INTEGER) = @@ -2752,11 +2725,12 @@ u.wr.NL (); END; - IF NOT u.vstack.doinsert_mn(t, m, n) THEN - u.vstack.pushimmI(m, Type.Word32); - u.vstack.pushimmI(n, Type.Word32); - u.insert(t); + IF u.vstack.doinsert_mn(t, m, n) THEN + RETURN; END; + u.vstack.pushimmI(m, Type.Word32); + u.vstack.pushimmI(n, Type.Word32); + u.insert(t); END insert_mn; (*------------------------------------------------ misc. stack/memory ops ---*) @@ -2784,6 +2758,7 @@ END; u.vstack.unlock(); + IF Target.FloatType [t] THEN WITH stack0 = u.vstack.pos(0, "pop") DO <* ASSERT u.vstack.loc(stack0) = OLoc.fstack *> @@ -2797,7 +2772,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: TIntN.T; n: INTEGER; mover := Mover [overlap]; + VAR n: INTEGER; mover := Mover [overlap]; + shift: Target.IntN; BEGIN IF u.debug THEN u.wr.Cmd ("copy_n"); @@ -2809,7 +2785,7 @@ WITH stack0 = u.vstack.pos(0, "copy_n") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - IF NOT TIntN.ToInt(u.vstack.op(stack0).imm, n) THEN + IF NOT TIntN.ToHostInteger(u.vstack.op(stack0).imm, n) THEN u.Err("copy_n: unable to convert to host integer"); END; u.vstack.discard(1); @@ -2872,7 +2848,7 @@ END inline_copy; PROCEDURE string_copy (u: U; n, size: INTEGER; forward: BOOLEAN) = - VAR tn, tNMinus1, tsize, tint: TIntN.T; + VAR tn, tNMinus1, tsize, tint: Target.IntN; BEGIN u.vstack.corrupt(ECX, operandPart := 0); u.cg.movImmI(u.cg.reg[ECX], n); @@ -2880,10 +2856,10 @@ IF forward THEN u.cg.noargOp(Op.oCLD); ELSE - IF NOT TIntN.FromInt(n, Target.Integer.bytes, tn) THEN + IF NOT TIntN.FromHostInteger(n, Target.Integer.bytes, tn) THEN u.Err("string_copy: unable to convert n to target int"); END; - IF NOT TIntN.FromInt(size, Target.Integer.bytes, tsize) THEN + IF NOT TIntN.FromHostInteger(size, Target.Integer.bytes, tsize) THEN u.Err("string_copy: unable to convert size to target int"); END; IF NOT TIntN.Subtract(tn, TIntN.One, tNMinus1) THEN @@ -2987,7 +2963,8 @@ PROCEDURE zero_n (u: U; z: IType; t: MType) = (* Mem[s1.A:s0.z] := 0; pop(2) *) - VAR shift: TIntN.T; n: INTEGER; + VAR n: INTEGER; + shift: Target.IntN; BEGIN IF u.debug THEN u.wr.Cmd ("zero_n"); @@ -2998,7 +2975,7 @@ WITH stack0 = u.vstack.pos(0, "zero_n") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - IF NOT TIntN.ToInt(u.vstack.op(stack0).imm, n) THEN + IF NOT TIntN.ToHostInteger(u.vstack.op(stack0).imm, n) THEN u.Err("zero_n: unable to convert to host integer"); END; u.vstack.discard(1); @@ -3169,8 +3146,8 @@ desc = BuiltinDesc [b] DO IF proc = NIL THEN proc := import_procedure (u, M3ID.Add (desc.name), - desc.n_params, desc.ret_type, - Target.FindConvention (desc.lang)); + desc.n_params, desc.ret_type, + Target.FindConvention (desc.lang)); FOR i := 1 TO desc.n_params DO EVAL declare_param (u, M3ID.NoID, 4, 4, Type.Word32, 0, FALSE, FALSE, 100); END; @@ -3245,9 +3222,10 @@ END; END check_nil; -PROCEDURE check_lo (u: U; t: IType; READONLY i: Target.Int; code: RuntimeError) = +PROCEDURE check_lo (u: U; t: IType; READONLY j: Target.Int; code: RuntimeError) = (* IF (s0.t < i) THEN abort(code) *) - VAR int: TIntN.T; safelab: Label; + VAR safelab: Label; + i := TIntN.FromTargetInt(j, CG_Bytes[t]); BEGIN IF u.debug THEN u.wr.Cmd ("check_lo"); @@ -3257,37 +3235,34 @@ u.wr.NL (); END; - IF NOT TIntN.FromTInt(i, CG_Bytes[t], int) THEN - u.Err("Failed to convert target integer in check_lo"); - END; - u.vstack.unlock(); WITH stack0 = u.vstack.pos(0, "check_lo") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - IF TIntN.LT(u.vstack.op(stack0).imm, int) THEN + IF TIntN.LT(u.vstack.op(stack0).imm, i) THEN reportfault(u, code); END ELSE u.vstack.find(stack0, Force.anyreg); - IF TIntN.GE(u.vstack.lower(u.vstack.reg(stack0)), int) THEN + IF TIntN.GE(u.vstack.lower(u.vstack.reg(stack0)), i) THEN (* ok *) - ELSIF TIntN.LT(u.vstack.upper(u.vstack.reg(stack0)), int) THEN + ELSIF TIntN.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 END check_lo; -PROCEDURE check_hi (u: U; t: IType; READONLY i: Target.Int; code: RuntimeError) = +PROCEDURE check_hi (u: U; t: IType; READONLY j: Target.Int; code: RuntimeError) = (* IF (i < s0.t) THEN abort(code) *) - VAR int: TIntN.T; safelab: Label; + VAR safelab: Label; + i := TIntN.FromTargetInt(j, CG_Bytes[t]); BEGIN IF u.debug THEN u.wr.Cmd ("check_hi"); @@ -3297,37 +3272,36 @@ u.wr.NL (); END; - IF NOT TIntN.FromTInt(i, CG_Bytes[t], int) THEN - u.Err("Failed to convert target integer in check_hi"); - END; - u.vstack.unlock(); WITH stack0 = u.vstack.pos(0, "check_hi") DO IF u.vstack.loc(stack0) = OLoc.imm THEN - IF TIntN.LT(int, u.vstack.op(stack0).imm) THEN + IF TIntN.LT(i, u.vstack.op(stack0).imm) THEN reportfault(u, code); END ELSE u.vstack.find(stack0, Force.anyreg); - IF TIntN.LE(u.vstack.upper(u.vstack.reg(stack0)), int) THEN + IF TIntN.LE(u.vstack.upper(u.vstack.reg(stack0)), i) THEN (* ok *) - ELSIF TIntN.GT(u.vstack.lower(u.vstack.reg(stack0)), int) THEN + ELSIF TIntN.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 END check_hi; -PROCEDURE check_range (u: U; t: IType; READONLY a, b: Target.Int; code: RuntimeError) = +PROCEDURE check_range (u: U; t: IType; READONLY xa, xb: Target.Int; code: RuntimeError) = (* IF (s0.t < a) OR (b < s0.t) THEN abort(code) *) - VAR inta, intb, lo, hi: TIntN.T; safelab, outrange: Label; + VAR lo, hi: Target.IntN; + safelab, outrange: Label; + a := TIntN.FromTargetInt(xa, CG_Bytes[t]); + b := TIntN.FromTargetInt(xb, CG_Bytes[t]); BEGIN IF u.debug THEN u.wr.Cmd ("check_range"); @@ -3337,18 +3311,11 @@ u.wr.NL (); END; - IF NOT TIntN.FromTInt(a, CG_Bytes[t], inta) THEN - u.Err("Failed to convert target integer in check_range"); - END; - IF NOT TIntN.FromTInt(b, CG_Bytes[t], intb) THEN - u.Err("Failed to convert target integer in check_range"); - END; - 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 TIntN.LT(lo, inta) OR TIntN.LT(intb, lo) THEN + IF TIntN.LT(lo, a) OR TIntN.LT(b, lo) THEN reportfault(u, code); END; RETURN; @@ -3358,42 +3325,45 @@ WITH reg = u.vstack.reg(stack0) DO lo := u.vstack.lower(reg); hi := u.vstack.upper(reg); - IF TIntN.LE(inta, lo) AND TIntN.LE(hi, intb) THEN + IF TIntN.LE(a, lo) AND TIntN.LE(hi, b) THEN (* ok *) - ELSIF TIntN.LT(hi, inta) OR TIntN.LT(intb, lo) THEN + ELSIF TIntN.LT(hi, a) OR TIntN.LT(b, lo) THEN reportfault(u, code); - ELSIF TIntN.LE(hi, intb) THEN - check_lo(u, t, a, code); - ELSIF TIntN.GE(lo, inta) THEN - check_hi(u, t, b, code); - ELSIF TIntN.EQ(inta, TZero) THEN + ELSIF TIntN.LE(hi, b) THEN + check_lo(u, t, xa, code); + ELSIF TIntN.GE(lo, a) THEN + check_hi(u, t, xb, code); + ELSIF TIntN.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 END check_range; PROCEDURE check_index (u: U; t: IType; code: RuntimeError) = - (* IF NOT (0 <= s1.t < s0.t) THEN abort(code) END; pop *) + (* IF NOT (0 <= s1.t < s0.t) THEN + abort(code) + END; + pop *) (* s0.t is guaranteed to be positive so the unsigned check (s0.W <= s1.W) is sufficient. *) VAR safelab: Label; @@ -3440,7 +3410,9 @@ END check_index; PROCEDURE check_eq (u: U; t: IType; code: RuntimeError) = - (* IF (s0.t # s1.t) THEN abort(code); Pop (2) *) + (* IF (s0.t # s1.t) THEN + abort(code); + Pop (2) *) VAR safelab: Label; BEGIN IF u.debug THEN @@ -3514,7 +3486,7 @@ u.cg.rmCall(u.vstack.op(u.vstack.pos(0, "makereportproc"))); ELSIF (repproc # NIL) THEN start_call_direct(u, repproc, 0, Type.Void); - INC(u.call_param_size[u.in_proc_call-1], 4); (* remember error code *) + INC(u.call_param_size[u.in_proc_call - 1], 4); (* remember error code *) load_address(u, u.global_var, 0); pop_param(u, Type.Addr); call_direct(u, repproc, Type.Void); @@ -3529,7 +3501,7 @@ PROCEDURE add_offset (u: U; i: INTEGER) = (* s0.A := s0.A + i *) - VAR int, imm_plus_i: TIntN.T; + VAR ti, imm_plus_i: Target.IntN; BEGIN IF u.debug THEN u.wr.Cmd ("add_offset"); @@ -3537,21 +3509,21 @@ u.wr.NL (); END; - IF NOT TIntN.FromInt(i, Target.Integer.bytes, int) THEN + IF NOT TIntN.FromHostInteger(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 - IF NOT TIntN.Add(u.vstack.op(stack0).imm, int, imm_plus_i) THEN + IF NOT TIntN.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), int); + u.cg.immOp(Op.oADD, u.vstack.op(stack0), ti); u.vstack.newdest(u.vstack.op(stack0)); END @@ -3690,47 +3662,21 @@ PROCEDURE pop_param (u: U; t: MType) = (* pop s0 and make it the "next" parameter in the current call *) BEGIN - IF u.debug THEN + (*IF u.debug THEN u.wr.Cmd ("pop_param"); u.wr.TName (t); u.wr.NL (); - END; - - <* ASSERT u.in_proc_call > 0 *> - - u.vstack.unlock(); - 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[ESP], TIntN.Four); - ELSE - u.cg.immOp(Op.oSUB, u.cg.reg[ESP], TIntN.Eight); - END; - - u.cg.f_storeind(u.cg.reg[ESP], 0, t); - ELSE - u.vstack.find(stack0, Force.anyregimm); - VAR - opA: ARRAY OperandPart OF Operand; - size := SplitOperand(u.vstack.op(stack0), opA); - BEGIN - FOR i := size - 1 TO 0 BY -1 DO u.cg.pushOp(opA[i]) END; - END; - END; - END; + END;*) + load_stack_param(u, t, 0); u.vstack.discard(1); - IF CG_Bytes[t] <= 4 THEN - INC(u.call_param_size[u.in_proc_call-1], 4); - ELSE - <* ASSERT CG_Bytes[t] = 8 *> - INC(u.call_param_size[u.in_proc_call-1], 8); - END END pop_param; -PROCEDURE load_stack_param (u: U; t: ZType; depth: INTEGER) = +PROCEDURE load_stack_param (u: U; t: MType; depth: INTEGER) = (* make value at vstack[depth] the next parameter in the current call *) + VAR opA: ARRAY OperandPart OF Operand; + size: OperandSize; BEGIN IF u.debug THEN @@ -3745,13 +3691,20 @@ <* ASSERT u.in_proc_call > 0 *> WITH stack = u.vstack.pos(depth, "load_stack_param") DO - <* ASSERT NOT Target.FloatType [t] *> - u.vstack.find(stack, Force.anyregimm); - VAR - opA: ARRAY OperandPart OF Operand; + IF Target.FloatType [t] THEN + <* ASSERT depth = 0 *> + IF t = Type.Reel THEN + u.cg.immOp(Op.oSUB, u.cg.reg[ESP], TIntN.Four); + ELSE + u.cg.immOp(Op.oSUB, u.cg.reg[ESP], TIntN.Eight); + END; + u.cg.f_storeind(u.cg.reg[ESP], 0, t); + ELSE + u.vstack.find(stack, Force.anyregimm); size := SplitOperand(u.vstack.op(stack), opA); - BEGIN - FOR i := size - 1 TO 0 BY -1 DO u.cg.pushOp(opA[i]) END; + FOR i := size - 1 TO 0 BY -1 DO + u.cg.pushOp(opA[i]); + END; END; END; @@ -3761,6 +3714,7 @@ ELSE INC(u.call_param_size[u.in_proc_call - 1], 8); END + END load_stack_param; PROCEDURE pop_struct (u: U; s: ByteSize; a: Alignment) = @@ -3768,7 +3722,7 @@ * NOTE that we implement call by value, the struct is * copied to temporary space on the machine stack *) - VAR ts: TIntN.T; + VAR ts: Target.IntN; BEGIN IF u.debug THEN u.wr.Cmd ("pop_struct"); @@ -3781,23 +3735,24 @@ (* round struct size up to multiple of 4 or 8 *) - CASE a OF - | 4 => s := Word.And(s + 3, 16_FFFFFFFC); - | 8 => s := Word.And(s + 7, Alignmask[8]); + <* ASSERT a <= 4 OR a = 8 *> + IF a <= 4 THEN + s := Word.And(s + 3, 16_FFFFFFFC); ELSE - <*ASSERT FALSE*> + s := Word.And(s + 7, Alignmask[8]); END; u.vstack.unlock(); WITH stack0 = u.vstack.pos(0, "pop_struct") DO - IF s > 32 THEN - (* "large", use rep mov to copy it to the machine stack *) + IF NOT TIntN.FromHostInteger(s, Target.Integer.bytes, ts) THEN + u.Err("pop_struct: unable to convert s to target int"); + END; - IF NOT TIntN.FromInt(s, Target.Integer.bytes, ts) THEN - u.Err("pop_struct: unable to convert s to target int"); - END; + (* if the struct is "large", use rep mov to copy it to the machine stack *) + + IF TIntN.GT(ts, TIntN.ThirtyTwo) THEN u.cg.immOp(Op.oSUB, u.cg.reg[ESP], ts); u.vstack.find(stack0, Force.regset, RegSet { ESI }); @@ -3813,7 +3768,8 @@ u.vstack.newdest(u.cg.reg[ESI]); ELSE - (* "small", use a few load/push to copy it to the machine stack *) + + (* if the struct is "small", use a few load/push to copy it to the machine stack *) u.vstack.find(stack0, Force.anyreg, RegSet {}, TRUE); @@ -3828,7 +3784,7 @@ u.vstack.discard(1); - INC(u.call_param_size[u.in_proc_call-1], s); + INC(u.call_param_size[u.in_proc_call - 1], s); END pop_struct; PROCEDURE pop_static_link (u: U) = @@ -3840,41 +3796,53 @@ <* ASSERT u.in_proc_call > 0 *> - u.static_link[u.in_proc_call-1] := declare_temp(u, 4, 4, Type.Addr, FALSE); + u.static_link[u.in_proc_call - 1] := declare_temp(u, 4, 4, Type.Addr, FALSE); - u.vstack.pop(MVar {var := u.static_link[u.in_proc_call-1], - offset := 0, type := Type.Addr} ); + u.vstack.pop(MVar {var := u.static_link[u.in_proc_call - 1], + mvar_offset := 0, mvar_type := Type.Addr} ); END pop_static_link; +PROCEDURE Is64 (t: Type): BOOLEAN = + BEGIN + RETURN t IN (SET OF Type{Type.Int64, Type.Word64}); + END Is64; + +PROCEDURE IsWord (t: Type): BOOLEAN = + BEGIN + RETURN t IN (SET OF Type{Type.Word32, Type.Word64}); + END IsWord; + +PROCEDURE IsInt (t: Type): BOOLEAN = + BEGIN + RETURN t IN (SET OF Type{Type.Int32, Type.Int64}); + END IsInt; + PROCEDURE SplitMVar(READONLY mvar: MVar; VAR mvarA: ARRAY OperandPart OF MVar): OperandSize = - VAR type := mvar.type; + VAR type := mvar.mvar_type; BEGIN mvarA[0] := mvar; - CASE type OF - | Type.Int64, Type.Word64 => - (* continue *) - ELSE + IF NOT Is64(type) THEN RETURN 1; END; mvarA[1] := mvar; IF mvar.var # NIL THEN (* <* ASSERT mvar.var.var_size = CG_Bytes[type] *> *) END; - INC(mvarA[1].offset, 4); - mvarA[0].type := Type.Word32; (* low part of 64bit integer is always unsigned *) + INC(mvarA[1].mvar_offset, 4); + mvarA[0].mvar_type := Type.Word32; (* low part of 64bit integer is always unsigned *) IF type = Type.Int64 THEN - mvarA[1].type := Type.Int32; (* high part signedness is same as unsplit type *) + mvarA[1].mvar_type := Type.Int32; (* high part signedness is same as unsplit type *) ELSIF type = Type.Word64 THEN - mvarA[1].type := Type.Word32; (* high part signedness is same as unsplit type *) + mvarA[1].mvar_type := Type.Word32; (* high part signedness is same as unsplit type *) ELSE <* ASSERT FALSE *> END; RETURN 2; END SplitMVar; -PROCEDURE SplitImm(type: Type; READONLY imm: TIntN.T; VAR immA: ARRAY OperandPart OF TIntN.T): OperandSize = +PROCEDURE SplitImm(type: Type; READONLY imm: Target.IntN; VAR immA: ARRAY OperandPart OF Target.IntN): OperandSize = BEGIN - TWordN.And(imm, TWordN.Max32, immA[0]); + TWordN.And(imm, Target.Word32.maxN, immA[0]); TWordN.RightShift(imm, 32, immA[1]); RETURN GetTypeSize(type); END SplitImm; @@ -3882,7 +3850,7 @@ PROCEDURE GetTypeSize(type: Type): OperandSize = (* In words: 1 or 2 *) BEGIN - RETURN 1 + ORD(type IN Types64); + RETURN 1 + ORD(Is64(type)); END GetTypeSize; PROCEDURE GetOperandSize(READONLY op: Operand): OperandSize = @@ -3893,14 +3861,11 @@ PROCEDURE SplitOperand(READONLY op: Operand; VAR opA: ARRAY OperandPart OF Operand): OperandSize = VAR type := op.optype; mvarA: ARRAY OperandPart OF MVar; - immA: ARRAY OperandPart OF TIntN.T; + immA: ARRAY OperandPart OF Target.IntN; BEGIN opA[0] := op; - CASE type OF - | Type.Int64, Type.Word64 => - (* continue *) - ELSE + IF GetTypeSize(type) = 1 THEN RETURN 1; END; @@ -3933,7 +3898,7 @@ PROCEDURE call_direct (u: U; p: Proc; t: Type) = VAR realproc := NARROW(p, x86Proc); - call_param_size: TIntN.T; + call_param_size: Target.IntN; (* call the procedure identified by block b. The procedure returns a value of type t. *) BEGIN @@ -3965,9 +3930,9 @@ END; IF (NOT realproc.stdcall) (* => caller cleans *) - AND u.call_param_size[u.in_proc_call-1] > 0 THEN - IF NOT TIntN.FromInt(u.call_param_size[u.in_proc_call-1], - Target.Integer.bytes, call_param_size) THEN + AND u.call_param_size[u.in_proc_call - 1] > 0 THEN + + IF NOT TIntN.FromHostInteger(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[ESP], call_param_size); @@ -3978,11 +3943,10 @@ END; IF t # Type.Void THEN - CASE t OF - | Type.Reel, Type.LReel, Type.XReel => + IF Target.FloatType [t] THEN u.vstack.pushnew(t, Force.any); u.cg.f_pushnew(); - | Type.Int64, Type.Word64 => + ELSIF Is64(t) THEN u.vstack.pushnew(t, Force.regset, RegSet { EAX, EDX }); ELSE u.vstack.pushnew(FixReturnValue(u, t), Force.regset, RegSet { EAX }); @@ -3995,7 +3959,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: TIntN.T; + VAR call_param_size: Target.IntN; BEGIN IF u.debug THEN u.wr.Cmd ("call_indirect"); @@ -4008,28 +3972,29 @@ u.vstack.releaseall(); - IF u.static_link[u.in_proc_call-1] # NIL THEN + IF u.static_link[u.in_proc_call - 1] # NIL THEN + (*u.vstack.corrupt(ECX, operandPart := 0);*) u.cg.movOp(u.cg.reg[ECX], - Operand { loc := OLoc.mem, - optype := Type.Addr, + Operand { loc := OLoc.mem, optype := Type.Addr, mvar := - MVar { var := u.static_link[u.in_proc_call-1], - offset := 0, - type := Type.Addr } } ); - free_temp(u, u.static_link[u.in_proc_call-1]); - u.static_link[u.in_proc_call-1] := NIL; + MVar { var := u.static_link[u.in_proc_call - 1], + mvar_offset := 0, + mvar_type := Type.Addr } } ); + free_temp(u, u.static_link[u.in_proc_call - 1]); + u.static_link[u.in_proc_call - 1] := NIL; END; u.cg.rmCall(u.vstack.op(u.vstack.pos(0, "call_indirect"))); u.vstack.discard(1); - IF (cc.m3cg_id = 0) - AND u.call_param_size[u.in_proc_call-1] > 0 THEN + IF (cc.m3cg_id = 0) AND u.call_param_size[u.in_proc_call - 1] > 0 THEN + (* caller-cleans calling convention *) - IF NOT TIntN.FromInt(u.call_param_size[u.in_proc_call - 1], - Target.Integer.bytes, call_param_size) THEN + + IF NOT TIntN.FromHostInteger(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[ESP], call_param_size); END; @@ -4038,11 +4003,10 @@ END; IF t # Type.Void THEN - CASE t OF - | Type.Reel, Type.LReel, Type.XReel => + IF Target.FloatType [t] THEN u.vstack.pushnew(t, Force.any); u.cg.f_pushnew(); - | Type.Int64, Type.Word64 => + ELSIF Is64(t) THEN u.vstack.pushnew(t, Force.regset, RegSet { EAX, EDX }); ELSE u.vstack.pushnew(FixReturnValue(u, t), Force.regset, RegSet { EAX }); @@ -4071,11 +4035,11 @@ t := Type.Int32; | Type.Word8 => (* 8-bit unsigned integer *) - u.cg.immOp (Op.oAND, u.cg.reg[EAX], TWordN.Max8); (* EAX &= 16_FF *) + u.cg.immOp (Op.oAND, u.cg.reg[EAX], Target.Word8.maxN); (* EAX &= 16_FF *) t := Type.Word32; | Type.Word16 => (* 16-bit unsigned integer *) - u.cg.immOp (Op.oAND, u.cg.reg[EAX], TWordN.Max16); (* EAX &= 16_FFFF *) + u.cg.immOp (Op.oAND, u.cg.reg[EAX], Target.Word16.maxN); (* EAX &= 16_FFFF *) t := Type.Word32; ELSE (* value is ok *) @@ -4182,25 +4146,23 @@ PROCEDURE condset (u: U; cond: Cond; t: ZType) = VAR reversed := FALSE; BEGIN - CASE t OF - | Type.Int32, Type.Int64 => - reversed := intregcmp(u, cond < Cond.E, t); - IF reversed THEN - cond := revcond[cond]; - END; - | Type.Word32, Type.Word64, Type.Addr => - reversed := intregcmp(u, cond < Cond.E, t); - IF reversed THEN - cond := revcond[cond]; - END; - cond := unscond[cond]; - | Type.Reel, Type.LReel, Type.XReel => + IF Target.FloatType[t] THEN reversed := fltregcmp(u, cond < Cond.E); - IF reversed THEN - cond := revcond[cond]; - END; - cond := unscond[cond]; (* FCOM sets the unsigned compare flags *) + ELSE + reversed := intregcmp(u, cond < Cond.E, t); + END; + + IF reversed THEN + cond := revcond[cond]; END; + + CASE t OF + | Type.Word32, Type.Word64, Type.Addr, + Type.Reel, Type.LReel, Type.XReel => (* FCOM sets the unsigned compare flags *) + cond := unscond[cond]; + ELSE + END; + u.vstack.unlock(); u.vstack.pushnew(Type.Word8, Force.mem); WITH stop0 = u.vstack.op(u.vstack.pos(0, "condset")) DO @@ -4224,10 +4186,15 @@ PROCEDURE Cmt (u: U; t: TEXT; VAR width: INTEGER) = VAR ch: CHAR; BEGIN - IF (NOT u.debug OR t = NIL) THEN RETURN END; + IF (NOT u.debug) OR (t = NIL) THEN + RETURN + END; FOR i := 0 TO Text.Length (t) - 1 DO ch := Text.GetChar (t, i); - IF (width = -1) THEN u.wr.OutT ("\t# "); width := 0; END; + IF (width = -1) THEN + u.wr.OutT ("\t# "); + width := 0; + END; IF (ch = '\n') THEN u.wr.NL (); width := -1; @@ -4398,7 +4365,7 @@ IF u.current_proc.fenceVar = NIL THEN u.current_proc.fenceVar := get_temp_var(u, Type.Word32, 4, 4); END; - u.vstack.push(MVar{u.current_proc.fenceVar, type := Type.Word32}); + u.vstack.push(MVar{u.current_proc.fenceVar, mvar_type := Type.Word32}); u.vstack.pushnew(Type.Word32, Force.anyreg); EVAL u.vstack.dobin(Op.oXCHG, TRUE, TRUE, Type.Word32); u.vstack.discard(1); @@ -4454,11 +4421,7 @@ x.vstack.find(atomicVariable, Force.anyreg); x.cg.load_ind(rEAX, x.vstack.op(atomicVariable), 0, t); label := x.next_label(); - IF x.debug THEN - x.wr.OutT ("."); - x.wr.Lab (label); - x.wr.NL (); - END; + debug_set_label(x, label); x.cg.set_label(label); x.cg.movOp(x.cg.reg[rNewValue], x.cg.reg[EAX]); x.cg.binOp(AtomicOpToOp[atomic_op], x.cg.reg[rNewValue], x.vstack.op(operand)); Index: M3x86Rep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/M3x86Rep.i3,v retrieving revision 1.38 diff -u -r1.38 M3x86Rep.i3 --- M3x86Rep.i3 27 Feb 2010 00:49:44 -0000 1.38 +++ M3x86Rep.i3 27 Feb 2010 12:33:14 -0000 @@ -29,10 +29,10 @@ TYPE x86Var = Var OBJECT tag: INTEGER; - type: Type; + var_type: Type; name: Name; - size: ByteSize; - align: Alignment; + var_size: ByteSize; + var_align: Alignment; exported := FALSE; seg: Seg; symbol: INTEGER; @@ -56,7 +56,7 @@ TYPE x86Proc = Proc OBJECT tag: INTEGER; - type: Type; + proc_type: Type; name: Name; lev := 0; parent: x86Proc := NIL; @@ -79,11 +79,11 @@ TYPE MVar = RECORD var: x86Var; - offset: ByteOffset := 0; - type: MType; + mvar_offset: ByteOffset := 0; + mvar_type: MType; END; -CONST NoStore = MVar {var := NIL, type := FIRST(MType)}; +CONST NoStore = MVar {var := NIL, mvar_type := FIRST(MType)}; (* If an operand requires two registers, it has parts 0 and 1. * etc. This is used to implement multi precision integers, @@ -99,7 +99,7 @@ loc: OLoc; mvar: MVar := NoStore; reg : Regno := 0; (* seems like it should be -1 *) - imm: INTEGER := 0; (* This might change to Target.TIntN. *) + imm: INTEGER := 0; (* This might change to Target.IntN. *) stackp: INTEGER := 0; (* this field might go away; seems like it should be -1 *) opcode := FALSE; END; @@ -108,7 +108,7 @@ loc: OLoc; mvar: MVar := NoStore; reg := ARRAY OperandPart OF Regno{0, ..}; (* seems like it should be -1 *) - imm := TIntN.Zero; + imm: Target.IntN := TIntN.Zero; optype: Type := Type.Void; stackp: INTEGER := 0; (* seems like it should be -1 *) opcode := FALSE; @@ -137,12 +137,11 @@ (*ESP,*) (*EBP,*) ESI, EDI}; CONST RegistersForByteOperations = RegSet{EAX, EBX, ECX, EDX}; -CONST Unsigned = SET OF Type{Type.Word32, Type.Word64}; -CONST Signed = SET OF Type{Type.Int32, Type.Int64}; -CONST Types64 = SET OF Type{Type.Int64, Type.Word64}; - +PROCEDURE IsWord (t: Type): BOOLEAN; (* IsUnsigned *) +PROCEDURE IsInt (t: Type): BOOLEAN; (* IsSigned *) +PROCEDURE Is64 (t: Type): BOOLEAN; PROCEDURE SplitMVar(READONLY mvar: MVar; VAR mvarA: ARRAY OperandPart OF MVar): OperandSize; -PROCEDURE SplitImm(type: Type; READONLY imm: TIntN.T; VAR immA: ARRAY OperandPart OF TIntN.T): OperandSize; +PROCEDURE SplitImm(type: Type; READONLY imm: Target.IntN; VAR immA: ARRAY OperandPart OF Target.IntN): OperandSize; PROCEDURE SplitOperand(READONLY op: Operand; VAR opA: ARRAY OperandPart OF Operand): OperandSize; PROCEDURE GetOperandSize(READONLY op: Operand): OperandSize; PROCEDURE GetTypeSize(type: Type): OperandSize; @@ -152,11 +151,11 @@ CONST UnsignedType = ARRAY IType OF IType { Type.Word32, Type.Word32, Type.Word64, Type.Word64 }; -CONST MaximumShift = ARRAY IType OF TIntN.T { TIntN.ThirtyOne, TIntN.ThirtyOne, - TIntN.SixtyThree, TIntN.SixtyThree }; +CONST MaximumShift = ARRAY IType OF Target.IntN { TIntN.ThirtyOne, TIntN.ThirtyOne, + TIntN.SixtyThree, TIntN.SixtyThree }; -CONST MinimumShift = ARRAY IType OF TIntN.T { TIntN.MThirtyOne, TIntN.MThirtyOne, - TIntN.MSixtyThree, TIntN.MSixtyThree }; +CONST MinimumShift = ARRAY IType OF Target.IntN { TIntN.MThirtyOne, TIntN.MThirtyOne, + TIntN.MSixtyThree, TIntN.MSixtyThree }; CONST BitCountMask = MaximumShift; Index: Stackx86.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Stackx86.i3,v retrieving revision 1.22 diff -u -r1.22 Stackx86.i3 --- Stackx86.i3 27 Feb 2010 00:49:44 -0000 1.22 +++ Stackx86.i3 27 Feb 2010 12:33:14 -0000 @@ -11,7 +11,7 @@ FROM M3CG IMPORT Type, MType, ZType, IType, Sign, ByteOffset; FROM M3CG_Ops IMPORT ErrorHandler; -IMPORT M3x86Rep, Codex86, Wrx86, TIntN; +IMPORT M3x86Rep, Codex86, Wrx86, Target; FROM M3x86Rep IMPORT Operand, OLoc, MVar, Regno, Force, RegSet, FlToInt; FROM M3x86Rep IMPORT x86Proc, x86Var, OperandPart; @@ -34,7 +34,7 @@ corrupt (reg: Regno; operandPart: OperandPart); set_fstack (stackp: INTEGER); set_mvar (stackp: INTEGER; READONLY mvar: MVar); - set_imm (stackp: INTEGER; READONLY imm: TIntN.T); + set_imm (stackp: INTEGER; READONLY imm: Target.IntN); loc (stackp: INTEGER): OLoc; op (stackp: INTEGER): Operand; pos (depth: INTEGER; place: TEXT): INTEGER; @@ -43,7 +43,7 @@ push (READONLY mvar: MVar); pushnew (type: MType; force: Force; set := RegSet {}); pushimmI (imm: INTEGER; type: Type); - pushimmT (imm: TIntN.T; type: Type); + pushimmT (imm: Target.IntN; type: Type); pop (READONLY mvar: MVar); doloadaddress (v: x86Var; o: ByteOffset); dobin (op: Op; symmetric, overwritesdest: BOOLEAN; type: Type): BOOLEAN; @@ -70,16 +70,16 @@ doindex_address (shift, size: INTEGER; neg: BOOLEAN); docopy (type: MType; overlap: BOOLEAN); docopy_n (n: INTEGER; type: MType; overlap: BOOLEAN); - doimm (op: Op; READONLY imm: TIntN.T; overwritesdest: BOOLEAN); + doimm (op: Op; READONLY imm: Target.IntN; overwritesdest: BOOLEAN); newdest (READONLY op: Operand); init (); end (); set_current_proc (p: x86Proc); reg (stackp: INTEGER): Regno; - lower (reg: Regno): TIntN.T; - set_lower (reg: Regno; low: TIntN.T); - upper (reg: Regno): TIntN.T; - set_upper (reg: Regno; up: TIntN.T); + lower (reg: Regno): Target.IntN; + set_lower (reg: Regno; low: Target.IntN); + upper (reg: Regno): Target.IntN; + set_upper (reg: Regno; up: Target.IntN); non_nil (reg: Regno): BOOLEAN; set_non_nil (reg: Regno); END; Index: Stackx86.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Stackx86.m3,v retrieving revision 1.103 diff -u -r1.103 Stackx86.m3 --- Stackx86.m3 27 Feb 2010 12:02:58 -0000 1.103 +++ Stackx86.m3 27 Feb 2010 12:33:14 -0000 @@ -1,4 +1,4 @@ -(* Copyright (C) 1993, Digital Equipment Corporation *) +(*Copyright (C) 1993, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* *) @@ -17,9 +17,9 @@ FROM M3CG IMPORT Type, MType, ZType, IType, Sign, Label, ByteOffset; FROM M3CG_Ops IMPORT ErrorHandler; -FROM M3x86Rep IMPORT Operand, MVar, Regno, OLoc, VLoc, NRegs, Force, Types64, OperandPart, RegName, OperandSize, TZero; +FROM M3x86Rep IMPORT Operand, MVar, Regno, OLoc, VLoc, NRegs, Force, Is64, OperandPart, RegName, OperandSize, TZero; FROM M3x86Rep IMPORT RegistersForByteOperations, RegSet, FlToInt, x86Var, x86Proc, NoStore, SplitOperand, SplitMVar, GetTypeSize, GetOperandSize; -FROM M3x86Rep IMPORT Unsigned, Signed, EAX, ECX, EDX, EBX, ESI, EDI, UnsignedType, MaximumShift, MinimumShift, BitCountMask, IntType; +FROM M3x86Rep IMPORT IsInt, IsWord, EAX, ECX, EDX, EBX, ESI, EDI, UnsignedType, MaximumShift, MinimumShift, BitCountMask, IntType; FROM Codex86 IMPORT Op, FOp, Cond, revcond; @@ -33,7 +33,7 @@ vstacklimit := 0; reguse : ARRAY [0 .. NRegs] OF Register; current_proc : x86Proc; - rmode : ARRAY FlToInt OF TIntN.T; + rmode : ARRAY FlToInt OF Target.IntN; lowset_table : x86Var; highset_table : x86Var; OVERRIDES @@ -102,15 +102,20 @@ Register = RECORD stackp : INTEGER := -1; last_store : MVar := NoStore; - last_imm : TIntN.T := TZero; - lowbound : TIntN.T := TIntN.Min32; - upbound : TIntN.T := TIntN.Max32; + last_imm : Target.IntN := TZero; + lowbound : Target.IntN; + upbound : Target.IntN; imm : BOOLEAN := FALSE; locked : BOOLEAN := FALSE; non_nil : BOOLEAN := FALSE; operandPart: OperandPart := 0; END; +PROCEDURE InitRegister(locked: BOOLEAN := FALSE):Register = +BEGIN + RETURN Register { locked := locked, lowbound := Target.Integer.minN, upbound := Target.Integer.maxN }; +END InitRegister; + (*-------------------------------------------- register handling routines ---*) CONST HighPrec: INTEGER = NRegs * 1000; @@ -183,7 +188,7 @@ BEGIN t.cg.movOp(t.cg.reg[r], op); - t.reguse[r] := Register { locked := t.reguse[r].locked }; + t.reguse[r] := InitRegister(locked := t.reguse[r].locked); t.reguse[r].stackp := op.stackp; t.reguse[r].operandPart := operandPart; @@ -255,8 +260,12 @@ t.cg.wrFlush(); FOR r := 0 TO NRegs DO + IF NOT (t.reguse[r].stackp = -1) THEN + t.Err("r:" & RegName[r] + & " t.reguse[r].stackp:" & Fmt.Int(t.reguse[r].stackp)); + END; <* ASSERT t.reguse[r].stackp = -1 *> - t.reguse[r] := Register {}; + t.reguse[r] := InitRegister(); END END clearall; @@ -265,7 +274,7 @@ t.cg.wrFlush(); FOR r := 0 TO NRegs DO - t.reguse[r] := Register {}; + t.reguse[r] := InitRegister(); END END releaseall; @@ -313,7 +322,7 @@ END; END; - IF op.mvar.type = Type.Addr THEN + IF op.mvar.mvar_type = Type.Addr THEN hintaddr := TRUE; END; @@ -343,7 +352,7 @@ RETURN; END; - IF force = Force.anydword AND in[0] = -1 AND in[size - 1] = -1 AND op.loc = OLoc.mem AND CG_Bytes[op.mvar.type] = (size * 4) THEN + IF force = Force.anydword AND in[0] = -1 AND in[size - 1] = -1 AND op.loc = OLoc.mem AND CG_Bytes[op.mvar.mvar_type] = (size * 4) THEN RETURN; END; @@ -353,7 +362,7 @@ RETURN; END; - IF op.loc = OLoc.mem AND CG_Bytes[op.mvar.type] = 1 THEN + IF op.loc = OLoc.mem AND CG_Bytes[op.mvar.mvar_type] = 1 THEN force := Force.regset; IF set = RegSet {} THEN set := RegistersForByteOperations; @@ -415,7 +424,7 @@ AND op.loc = OLoc.mem AND t.reguse[to[0 ]].stackp # -1 AND t.reguse[to[size - 1]].stackp # -1 - AND CG_Bytes[op.mvar.type] = (size * 4) THEN + AND CG_Bytes[op.mvar.mvar_type] = (size * 4) THEN RETURN; END; @@ -530,7 +539,7 @@ bestreg: Regno := -1; hintaddr := FALSE; BEGIN - IF v.type = Type.Addr THEN + IF v.mvar_type = Type.Addr THEN hintaddr := TRUE; END; @@ -549,7 +558,7 @@ RETURN bestreg; END inreg; -PROCEDURE immreg (t: T; READONLY imm: TIntN.T; set: RegSet:= RegSet {}): Regno = +PROCEDURE immreg (t: T; READONLY imm: Target.IntN; set: RegSet:= RegSet {}): Regno = VAR minprec := HighPrec * HighPrec; prec := 0; bestreg: Regno := -1; @@ -606,18 +615,18 @@ BEGIN set_mvar(t, stackp, MVar { var := t.parent.declare_temp(size * 4, 4, op.optype, FALSE), - offset := 0, type := op.optype } ); + mvar_offset := 0, mvar_type := op.optype } ); t.vstack[stackp].mvar.var.stack_temp := TRUE; CASE op.loc OF | OLoc.imm => t.cg.movImmT(t.vstack[stackp], op.imm); | OLoc.register => mvar := t.vstack[stackp].mvar; (* save away *) - t.vstack[stackp].mvar.type := Type.Word32; (* make it register sized *) + t.vstack[stackp].mvar.mvar_type := Type.Word32; (* make it register sized *) t.vstack[stackp].optype := Type.Word32; FOR i := 0 TO size - 1 DO t.reguse[op.reg[i]].stackp := -1; - t.vstack[stackp].mvar.offset := i * 4; (* offset to register sized chunk *) + t.vstack[stackp].mvar.mvar_offset := i * 4; (* offset to register sized chunk *) t.cg.movOp(t.vstack[stackp], t.cg.reg[op.reg[i]]); END; t.vstack[stackp].optype := op.optype; @@ -662,7 +671,7 @@ t.cg.movOp(t.cg.reg[ECX], stackOpA[1]); END; set_mvar(t, i, MVar { var := t.parent.declare_temp(size * 4, 4, type, FALSE), - offset := 0, type := type } ); + mvar_offset := 0, mvar_type := type } ); t.vstack[i].mvar.var.stack_temp := TRUE; IF size = 1 THEN t.cg.movOp(t.vstack[i], t.cg.reg[EAX]); @@ -704,7 +713,7 @@ IF t.reguse[reg].stackp # -1 THEN forceout(t, reg, operandPart); END; - t.reguse[reg] := Register { locked := t.reguse[reg].locked }; + t.reguse[reg] := InitRegister(locked := t.reguse[reg].locked); END corrupt; PROCEDURE all_to_mem(t: T) = @@ -727,7 +736,7 @@ t.vstack[stackp].mvar := mvar; END set_mvar; -PROCEDURE set_imm (t: T; stackp: INTEGER; READONLY imm: TIntN.T) = +PROCEDURE set_imm (t: T; stackp: INTEGER; READONLY imm: Target.IntN) = BEGIN t.vstack[stackp].loc := OLoc.imm; t.vstack[stackp].imm := imm; @@ -755,7 +764,7 @@ RETURN -1; END pos; -PROCEDURE pushimmT (t: T; imm: TIntN.T; type: Type) = +PROCEDURE pushimmT (t: T; imm: Target.IntN; type: Type) = BEGIN maybe_expand_stack(t); @@ -770,9 +779,9 @@ END pushimmT; PROCEDURE pushimmI (t: T; immI: INTEGER; type: Type) = - VAR immT: TIntN.T; + VAR immT: Target.IntN; BEGIN - IF NOT TIntN.FromInt(immI, Target.Integer.bytes, immT) THEN + IF NOT TIntN.FromHostInteger(immI, Target.Integer.bytes, immT) THEN t.Err("pushimmI: unable to convert to target integer"); END; t.pushimmT(immT, type); @@ -794,7 +803,7 @@ MVar { var := t.parent.declare_temp(CG_Bytes[type], CG_Align_bytes[type], type, FALSE), - offset := 0, type := type } ); + mvar_offset := 0, mvar_type := type } ); stack0.mvar.var.stack_temp := TRUE; ELSE corrupt(t, reg, operandPart); @@ -807,7 +816,7 @@ PROCEDURE pushnew (t: T; type: MType; force: Force; set := RegSet {}) = BEGIN maybe_expand_stack(t); - IF type IN Types64 AND force = Force.regset AND set = RegSet { EAX, EDX } THEN + IF Is64(type) AND force = Force.regset AND set = RegSet { EAX, EDX } THEN pushnew1(t, type, Force.regset, RegSet { EDX }, operandPart := 1); pushnew1(t, type, Force.regset, RegSet { EAX }, operandPart := 0); ELSE @@ -821,21 +830,21 @@ PROCEDURE push (t: T; READONLY src_mvar: MVar) = VAR indreg: Regno; destreg: ARRAY OperandPart OF Regno; - srcSize := GetTypeSize(src_mvar.type); + srcSize := GetTypeSize(src_mvar.mvar_type); BEGIN maybe_expand_stack(t); WITH stack0 = t.vstack[t.stacktop] DO stack0.stackp := t.stacktop; - stack0.optype := src_mvar.type; - IF FloatType [src_mvar.type] THEN + stack0.optype := src_mvar.mvar_type; + IF FloatType [src_mvar.mvar_type] THEN IF src_mvar.var.loc = VLoc.temp AND src_mvar.var.parent # t.current_proc THEN unlock(t); indreg := pickreg(t, RegSet {}, TRUE); corrupt(t, indreg, operandPart := 0); t.cg.get_frame(indreg, src_mvar.var.parent, t.current_proc); - t.cg.f_loadind(t.cg.reg[indreg], src_mvar.offset + src_mvar.var.offset, src_mvar.type); + t.cg.f_loadind(t.cg.reg[indreg], src_mvar.mvar_offset + src_mvar.var.offset, src_mvar.mvar_type); stack0.loc := OLoc.fstack; ELSE stack0.loc := OLoc.fstack; @@ -845,11 +854,11 @@ IF src_mvar.var.loc = VLoc.temp AND src_mvar.var.parent # t.current_proc THEN unlock(t); FOR i := 0 TO srcSize - 1 DO - IF CG_Bytes[src_mvar.type] = 1 THEN + IF CG_Bytes[src_mvar.mvar_type] = 1 THEN <* ASSERT srcSize = 1 AND i = 0 *> destreg[i] := pickreg(t, RegSet{EAX, EBX, ECX, EDX}); ELSE - destreg[i] := pickreg(t, RegSet {}, src_mvar.type = Type.Addr); + destreg[i] := pickreg(t, RegSet {}, src_mvar.mvar_type = Type.Addr); END; corrupt(t, destreg[i], operandPart := i); t.reguse[destreg[i]].locked := TRUE; @@ -860,8 +869,8 @@ t.cg.get_frame(indreg, src_mvar.var.parent, t.current_proc); FOR i := 0 TO srcSize - 1 DO - t.cg.load_ind(destreg[i], t.cg.reg[indreg], src_mvar.offset + src_mvar.var.offset + i * 4, - src_mvar.type); + t.cg.load_ind(destreg[i], t.cg.reg[indreg], src_mvar.mvar_offset + src_mvar.var.offset + i * 4, + src_mvar.mvar_type); set_reg(t, t.stacktop, destreg[i], operandPart := i); END; newdest(t, stack0); @@ -893,14 +902,14 @@ indreg := pickreg(t, RegSet {}, TRUE); corrupt(t, indreg, operandPart := 0); t.cg.get_frame(indreg, dest_mvar.var.parent, t.current_proc); - t.cg.f_storeind(t.cg.reg[indreg], dest_mvar.offset + dest_mvar.var.offset, dest_mvar.type); + t.cg.f_storeind(t.cg.reg[indreg], dest_mvar.mvar_offset + dest_mvar.var.offset, dest_mvar.mvar_type); ELSE t.cg.fstack_pop(dest_mvar); END ELSE unlock(t); - IF CG_Bytes[dest_mvar.type] = 1 AND src_stack0.loc # OLoc.imm THEN + IF CG_Bytes[dest_mvar.mvar_type] = 1 AND src_stack0.loc # OLoc.imm THEN find(t, t.stacktop - 1, Force.regset, RegSet { EAX, EBX, ECX, EDX } ); ELSE find(t, t.stacktop - 1, Force.anyregimm); @@ -910,7 +919,7 @@ IF NOT (srcSize = destSize) THEN t.Err(" srcSize:" & Fmt.Int(srcSize) & " destSize:" & Fmt.Int(destSize) - & " dest_mvar.type:" & Target.TypeNames[dest_mvar.type] + & " dest_mvar.mvar_type:" & Target.TypeNames[dest_mvar.mvar_type] & " src_stack0.optype:" & Target.TypeNames[src_stack0.optype]); END; <* ASSERT srcSize = destSize *> @@ -922,8 +931,8 @@ FOR i := 0 TO destSize - 1 DO t.cg.store_ind(src_opA[i], t.cg.reg[indreg], - dest_mvarA[i].offset + dest_mvarA[i].var.offset, - dest_mvarA[i].type); + dest_mvarA[i].mvar_offset + dest_mvarA[i].var.offset, + dest_mvarA[i].mvar_type); t.reguse[src_stack0.reg[i]].stackp := -1; corrupt(t, src_stack0.reg[i], i); END; @@ -947,7 +956,7 @@ END; FOR i := 0 TO destSize - 1 DO - t.cg.movOp(Operand { loc := OLoc.mem, mvar := dest_mvarA[i], optype := dest_mvarA[i].type }, src_opA[i]); + t.cg.movOp(Operand { loc := OLoc.mem, mvar := dest_mvarA[i], optype := dest_mvarA[i].mvar_type }, src_opA[i]); END; set_mvar(t, t.stacktop - 1, dest_mvar); END @@ -958,7 +967,7 @@ END pop; PROCEDURE doloadaddress (t: T; v: x86Var; o: ByteOffset) = - VAR to, tvoffset, ti: TIntN.T; + VAR to, tvoffset, ti: Target.IntN; BEGIN unlock(t); pushnew(t, Type.Addr, Force.anyreg); @@ -966,10 +975,10 @@ 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[0], v.parent, t.current_proc); - IF NOT TIntN.FromInt(o, Target.Integer.bytes, to) THEN + IF NOT TIntN.FromHostInteger(o, Target.Integer.bytes, to) THEN t.Err("doloadaddress: unable to convert o"); END; - IF NOT TIntN.FromInt(v.offset, Target.Integer.bytes, tvoffset) THEN + IF NOT TIntN.FromHostInteger(v.offset, Target.Integer.bytes, tvoffset) THEN t.Err("doloadaddress: unable to convert v.offset"); END; IF NOT TIntN.Add(to, tvoffset, ti) THEN @@ -979,8 +988,8 @@ ELSE t.cg.binOp(Op.oLEA, stop0, Operand {loc := OLoc.mem, optype := Type.Word32, - mvar := MVar {var := v, offset := o, - type := Type.Word32} } ); + mvar := MVar {var := v, mvar_offset := o, + mvar_type := Type.Word32} } ); END END END doloadaddress; @@ -1036,11 +1045,11 @@ END; IF destop.loc = OLoc.mem AND - (CG_Bytes[destop.mvar.type] < 4 OR srcop.loc = OLoc.mem) THEN + (CG_Bytes[destop.mvar.mvar_type] < 4 OR srcop.loc = OLoc.mem) THEN find(t, dest, Force.anyreg); END; - IF srcop.loc = OLoc.mem AND CG_Bytes[srcop.mvar.type] < 4 THEN + IF srcop.loc = OLoc.mem AND CG_Bytes[srcop.mvar.mvar_type] < 4 THEN find(t, src, Force.anyreg); END END; @@ -1306,7 +1315,7 @@ END END domod; -PROCEDURE doimm (t: T; op: Op; READONLY imm: TIntN.T; overwritesdest: BOOLEAN) = +PROCEDURE doimm (t: T; op: Op; READONLY imm: Target.IntN; overwritesdest: BOOLEAN) = BEGIN unlock(t); @@ -1314,8 +1323,8 @@ stop0 = t.vstack[stack0] DO IF (stop0.loc = OLoc.mem AND ((overwritesdest AND NOT stop0.mvar.var.stack_temp) OR - CG_Bytes[stop0.mvar.type] = 2 OR - (CG_Bytes[stop0.mvar.type] = 1 AND (TIntN.GT(imm, TIntN.Max8) OR TIntN.LT(imm, TIntN.Min8))))) + CG_Bytes[stop0.mvar.mvar_type] = 2 OR + (CG_Bytes[stop0.mvar.mvar_type] = 1 AND (TIntN.GT(imm, Target.Int8.maxN) OR TIntN.LT(imm, Target.Int8.minN))))) OR stop0.loc = OLoc.imm THEN find(t, stack0, Force.anyreg); ELSE @@ -1333,7 +1342,7 @@ END doimm; PROCEDURE doneg (t: T) = - VAR neg: TIntN.T; + VAR neg: Target.IntN; BEGIN unlock(t); WITH stack0 = pos(t, 0, "doneg"), @@ -1392,10 +1401,10 @@ PROCEDURE doshift (t: T; type: IType): BOOLEAN = VAR ovflshift, leftlab, endlab: Label; - tShiftCount: TIntN.T; - shiftResult: TIntN.T; + tShiftCount: Target.IntN; + shiftResult: Target.IntN; shiftCount: INTEGER; - is64 := type IN Types64; + is64 := Is64(type); BEGIN unlock(t); @@ -1406,7 +1415,7 @@ IF stop0.loc = OLoc.imm THEN IF stop1.loc = OLoc.imm THEN - IF NOT TIntN.ToInt(stop0.imm, shiftCount) THEN + IF NOT TIntN.ToHostInteger(stop0.imm, shiftCount) THEN t.Err("doshift: unable to convert target integer to host integer"); END; @@ -1506,7 +1515,7 @@ PROCEDURE dorotate (t: T; type: IType): BOOLEAN = VAR leftlab, endlab: Label; rotateCount: INTEGER; - is64 := type IN Types64; + is64 := Is64(type); BEGIN unlock(t); @@ -1517,7 +1526,7 @@ IF stop0.loc = OLoc.imm THEN IF stop1.loc = OLoc.imm THEN - IF NOT TIntN.ToInt(stop0.imm, rotateCount) THEN + IF NOT TIntN.ToHostInteger(stop0.imm, rotateCount) THEN t.Err("dorotate: failed to convert rotateCount to host integer"); END; TWordN.Rotate(stop1.imm, rotateCount, stop1.imm); @@ -1588,7 +1597,7 @@ PROCEDURE doextract (t: T; type: IType; sign: BOOLEAN): BOOLEAN = VAR tbl: MVar; int: INTEGER; - is64 := type IN Types64; + is64 := Is64(type); BEGIN unlock(t); @@ -1605,7 +1614,7 @@ IF stop0.loc = OLoc.imm THEN discard(t, 1); - IF NOT TIntN.ToInt(stop0.imm, int) THEN + IF NOT TIntN.ToHostInteger(stop0.imm, int) THEN t.Err("doextract: failed to convert to host integer"); END; RETURN doextract_n(t, type, sign, int); @@ -1620,7 +1629,7 @@ find(t, stack0, Force.regset, RegSet { ECX }); find(t, stack1, Force.any); find(t, stack2, Force.anyreg); - IF stop1.loc = OLoc.mem AND CG_Bytes[stop1.mvar.type] < 4 THEN + IF stop1.loc = OLoc.mem AND CG_Bytes[stop1.mvar.mvar_type] < 4 THEN find(t, stack1, Force.anyreg); END; @@ -1663,10 +1672,10 @@ END doextract; PROCEDURE doextract_n (t: T; type: IType; sign: BOOLEAN; n: INTEGER): BOOLEAN = - VAR tn, t32MinusN, andval: TIntN.T; + VAR tn, t32MinusN, andval: Target.IntN; int: INTEGER; uint_type := IntType[UnsignedType[type]]; - is64 := type IN Types64; + is64 := Is64(type); BEGIN unlock(t); @@ -1681,7 +1690,7 @@ IF stop0.loc = OLoc.imm THEN discard(t, 1); - IF NOT TIntN.ToInt(stop0.imm, int) THEN + IF NOT TIntN.ToHostInteger(stop0.imm, int) THEN t.Err("doextract_n: failed to convert to host integer"); END; RETURN doextract_mn(t, type, sign, int, n); @@ -1693,11 +1702,11 @@ find(t, stack0, Force.any); find(t, stack1, Force.anyreg); - IF stop0.loc = OLoc.mem AND CG_Bytes[stop0.mvar.type] < 4 THEN + IF stop0.loc = OLoc.mem AND CG_Bytes[stop0.mvar.mvar_type] < 4 THEN find(t, stack0, Force.anyreg); END; - IF NOT TIntN.FromInt(n, Target.Integer.bytes, tn) THEN + IF NOT TIntN.FromHostInteger(n, Target.Integer.bytes, tn) THEN t.Err("doextract_n: failed to convert n to target integer"); END; @@ -1719,10 +1728,7 @@ t.cg.unOp(Op.oSHR, stop1); IF n < uint_type.size THEN - IF is64 - THEN TWordN.Shift(TWordN.Max64, n - uint_type.size, andval); - ELSE TWordN.Shift(TWordN.Max32, n - uint_type.size, andval); - END; + TWordN.Shift(uint_type.maxN, n - uint_type.size, andval); t.cg.immOp(Op.oAND, stop1, andval); END END; @@ -1735,8 +1741,8 @@ END doextract_n; PROCEDURE doextract_mn (t: T; type: IType; sign: BOOLEAN; m, n: INTEGER): BOOLEAN = - VAR andval, tint: TIntN.T; - is64 := type IN Types64; + VAR andval, tint: Target.IntN; + is64 := Is64(type); BEGIN unlock(t); @@ -1749,13 +1755,13 @@ IF stop0.loc = OLoc.imm THEN TWordN.Shift(stop0.imm, -m, stop0.imm); - TWordN.Shift(TWordN.Max32, n - 32, tint); + TWordN.Shift(Target.Word32.maxN, n - 32, tint); TWordN.And(stop0.imm, tint, stop0.imm); IF sign THEN TWordN.Shift(TIntN.One, n - 1, tint); TWordN.And(stop0.imm, tint, tint); IF TIntN.NE(tint, TZero) THEN - TWordN.Shift(TWordN.Max32, n, tint); + TWordN.Shift(Target.Word32.maxN, n, tint); TWordN.Or(stop0.imm, tint, stop0.imm); END; END; @@ -1765,14 +1771,14 @@ IF sign THEN find(t, stack0, Force.anyreg); IF (m + n) < 32 THEN - IF NOT TIntN.FromInt(32 - (m + n), Target.Integer.bytes, tint) THEN + IF NOT TIntN.FromHostInteger(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.oSHL, stop0, tint); END; IF n < 32 THEN - IF NOT TIntN.FromInt(32 - n, Target.Integer.bytes, tint) THEN + IF NOT TIntN.FromHostInteger(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); @@ -1780,12 +1786,12 @@ ELSE find(t, stack0, Force.anyreg); IF (m + n) < 32 THEN - TWordN.Shift(TWordN.Max32, m + n - 32, andval); + TWordN.Shift(Target.Word32.maxN, m + n - 32, andval); t.cg.immOp(Op.oAND, stop0, andval); END; IF m > 0 THEN - IF NOT TIntN.FromInt(m, Target.Integer.bytes, tint) THEN + IF NOT TIntN.FromHostInteger(m, Target.Integer.bytes, tint) THEN t.Err("doextract_mn: failed to m to target integer"); END; t.cg.immOp(Op.oSHR, stop0, tint); @@ -1801,8 +1807,8 @@ PROCEDURE doinsert (t: T; type: IType): BOOLEAN = VAR maskreg: Regno; tbl: MVar; int: INTEGER; - tint: TIntN.T; - is64 := type IN Types64; + tint: Target.IntN; + is64 := Is64(type); BEGIN unlock(t); @@ -1821,7 +1827,7 @@ IF stop0.loc = OLoc.imm THEN discard(t, 1); - IF NOT TIntN.ToInt(stop0.imm, int) THEN + IF NOT TIntN.ToHostInteger(stop0.imm, int) THEN t.Err("doinsert: failed to convert to host integer"); END; RETURN doinsert_n(t, type, int); @@ -1866,10 +1872,10 @@ t.cg.tableOp(Op.oMOV, t.cg.reg[maskreg], stop0, 4, tbl); IF stop1.loc = OLoc.imm THEN - IF NOT TIntN.ToInt(stop1.imm, int) THEN + IF NOT TIntN.ToHostInteger(stop1.imm, int) THEN t.Err("failed to convert stop1.imm to host integer"); END; - TWordN.Shift(TWordN.Max32, int, tint); + TWordN.Shift(Target.Word32.maxN, int, tint); t.cg.immOp(Op.oXOR, t.cg.reg[maskreg], tint); ELSE ImportHighSet (t, tbl); @@ -1891,8 +1897,8 @@ PROCEDURE doinsert_n (t: T; type: IType; n: INTEGER): BOOLEAN = VAR tbl: MVar; maskreg: Regno; m: INTEGER; - tint: TIntN.T; - is64 := type IN Types64; + tint: Target.IntN; + is64 := Is64(type); BEGIN unlock(t); @@ -1909,7 +1915,7 @@ IF stop0.loc = OLoc.imm THEN discard(t, 1); - IF NOT TIntN.ToInt(stop0.imm, m) THEN + IF NOT TIntN.ToHostInteger(stop0.imm, m) THEN t.Err("doinsert_n: failed to convert to host integer"); END; RETURN doinsert_mn(t, type, m, n); @@ -1927,7 +1933,7 @@ corrupt(t, maskreg, operandPart := 0); IF n # 32 THEN - TWordN.Shift(TWordN.Max32, n - 32, tint); + TWordN.Shift(Target.Word32.maxN, n - 32, tint); t.cg.immOp(Op.oAND, stop1, tint); END; @@ -1942,7 +1948,7 @@ ImportLowSet(t, tbl); t.cg.tableOp(Op.oMOV, t.cg.reg[maskreg], stop0, 4, tbl); ImportHighSet(t, tbl); - INC(tbl.offset, n*4); + INC(tbl.mvar_offset, n*4); t.cg.tableOp(Op.oXOR, t.cg.reg[maskreg], stop0, 4, tbl); t.cg.binOp(Op.oAND, stop2, t.cg.reg[maskreg]); @@ -1957,15 +1963,10 @@ END doinsert_n; PROCEDURE doinsert_mn (t: T; type: IType; m, n: INTEGER): BOOLEAN = - VAR tint_m, mask_m, mask_m_n, mask: TIntN.T; + VAR tint_m, mask_m, mask_m_n, mask: Target.IntN; uint_type := IntType[UnsignedType[type]]; - is64 := type IN Types64; - Max: TIntN.T; + is64 := Is64(type); BEGIN - IF is64 - THEN Max := TWordN.Max64; - ELSE Max := TWordN.Max32; - END; unlock(t); WITH stack0 = pos(t, 0, "insert"), @@ -1986,7 +1987,7 @@ find(t, stack1, Force.anyreg); END; - TWordN.Shift(Max, n - uint_type.size, mask); + TWordN.Shift(uint_type.maxN, n - uint_type.size, mask); IF stop0.loc = OLoc.imm THEN TWordN.And(stop0.imm, mask, stop0.imm); @@ -1997,18 +1998,18 @@ END; IF m # 0 THEN - IF NOT TIntN.FromInt(m, Target.Integer.bytes, tint_m) THEN + IF NOT TIntN.FromHostInteger(m, Target.Integer.bytes, tint_m) THEN t.Err("doinsert_mn: unable to convert m to target integer"); END; t.cg.immOp(Op.oSHL, stop0, tint_m); END END; - TWordN.Shift(Max, m, mask_m); - TWordN.Shift(Max, m + n - uint_type.size, mask_m_n); + TWordN.Shift(uint_type.maxN, m, mask_m); + TWordN.Shift(uint_type.maxN, m + n - uint_type.size, mask_m_n); TWordN.Xor(mask_m, mask_m_n, mask); - IF TWordN.NE(mask, Max) THEN + IF TWordN.NE(mask, uint_type.maxN) THEN IF stop1.loc = OLoc.imm THEN TWordN.And(stop1.imm, mask, stop1.imm); ELSE @@ -2114,7 +2115,7 @@ IF fromSize = 2 THEN find(t, stack0, Force.anyreg); ELSE - IF from IN Signed THEN + IF IsInt(from) THEN find(t, stack0, Force.regset, RegSet{EAX}); ELSE find(t, stack0, Force.anyreg); @@ -2134,7 +2135,7 @@ * We should favor dead, or else anything but * the one that holds the other half of this operand. *) - IF from IN Unsigned THEN + IF IsWord(from) THEN (* zero extend by allocating another register and xoring *) WITH reg = finddead(t) DO <* ASSERT reg # -1 *> @@ -2163,15 +2164,15 @@ CG_Align_bytes[to], to, FALSE); stop0.mvar.var.stack_temp := TRUE; - stop0.mvar.offset := 0; - stop0.mvar.type := from; + stop0.mvar.mvar_offset := 0; + stop0.mvar.mvar_type := from; t.cg.fstack_pop(stop0.mvar); - stop0.mvar.type := to; + stop0.mvar.mvar_type := to; ELSE <* ASSERT NOT fromFloat *> <* ASSERT toFloat *> - IF stop0.loc = OLoc.mem AND CG_Bytes[stop0.mvar.type] < 4 THEN + IF stop0.loc = OLoc.mem AND CG_Bytes[stop0.mvar.mvar_type] < 4 THEN find(t, stack0, Force.anyreg); END; @@ -2183,7 +2184,7 @@ **********************************************) <* ASSERT to = Type.Reel *> - stop0.mvar.type := to; + stop0.mvar.mvar_type := to; t.cg.fstack_push(stop0.mvar, TRUE); IF stop0.mvar.var.stack_temp THEN t.parent.free_temp(stop0.mvar.var); @@ -2196,9 +2197,9 @@ PROCEDURE doindex_address (t: T; shift, size: INTEGER; neg: BOOLEAN) = VAR imsize: INTEGER; muldest: Regno; - tsize: TIntN.T; - tshift: TIntN.T; - tint: TIntN.T; + tsize: Target.IntN; + tshift: Target.IntN; + tint: Target.IntN; BEGIN unlock(t); WITH stack0 = pos(t, 0, "doindex_address"), @@ -2209,7 +2210,7 @@ find(t, stack1, Force.anyreg, RegSet {}, TRUE); IF stop0.loc = OLoc.imm THEN - IF NOT TIntN.FromInt(size, Target.Integer.bytes, tsize) THEN + IF NOT TIntN.FromHostInteger(size, Target.Integer.bytes, tsize) THEN t.Err("doindex_address: failed to convert size to target integer"); END; IF NOT TIntN.Multiply(stop0.imm, tsize, tint) THEN @@ -2221,7 +2222,7 @@ find(t, stack0, Force.anyreg); END; IF stop0.loc = OLoc.mem AND shift < 0 AND - CG_Bytes[stop0.mvar.type] < 4 THEN + CG_Bytes[stop0.mvar.mvar_type] < 4 THEN find(t, stack0, Force.anydword); END; @@ -2244,7 +2245,7 @@ END ELSIF shift > 0 THEN - IF NOT TIntN.FromInt(shift, Target.Integer.bytes, tshift) THEN + IF NOT TIntN.FromHostInteger(shift, Target.Integer.bytes, tshift) THEN t.Err("doindex_address: failed to convert size to target integer"); END; t.cg.immOp(Op.oSHL, stop0, tshift); @@ -2375,11 +2376,11 @@ t.cg.noargFOp(FOp.fNCLEX); statusop := Operand { loc := OLoc.mem, optype := Type.Int32, - mvar := MVar { var := status, offset := 0, - type := Type.Int32 } }; + mvar := MVar { var := status, mvar_offset := 0, + mvar_type := Type.Int32 } }; newstat := Operand { loc := OLoc.mem, optype := Type.Int32, - mvar := MVar { var := status, offset := 4, - type := Type.Int32 } }; + mvar := MVar { var := status, mvar_offset := 4, + mvar_type := Type.Int32 } }; t.cg.memFOp(FOp.fSTCW, statusop.mvar); t.cg.movOp(t.cg.reg[statreg], statusop); @@ -2409,7 +2410,7 @@ BEGIN WITH stack0 = pos(t, 0, "inttoflt"), stop0 = t.vstack[stack0] DO - IF stop0.loc = OLoc.mem AND CG_Bytes[stop0.mvar.type] < 4 THEN + IF stop0.loc = OLoc.mem AND CG_Bytes[stop0.mvar.mvar_type] < 4 THEN unlock(t); find(t, stack0, Force.anyreg); END; @@ -2432,8 +2433,8 @@ FOR i := 0 TO GetTypeSize(op.optype) - 1 DO WITH z = t.reguse[op.reg[i]] DO z.last_store := NoStore; - z.upbound := TIntN.Max32; - z.lowbound := TIntN.Min32; + z.upbound := Target.Integer.maxN; + z.lowbound := Target.Integer.minN; z.imm := FALSE; z.non_nil := FALSE; END; @@ -2487,22 +2488,22 @@ RETURN t.vstack[stackp].reg[0]; END reg; -PROCEDURE lower (t: T; reg: Regno): TIntN.T = +PROCEDURE lower (t: T; reg: Regno): Target.IntN = BEGIN RETURN t.reguse[reg].lowbound; END lower; -PROCEDURE upper (t: T; reg: Regno): TIntN.T = +PROCEDURE upper (t: T; reg: Regno): Target.IntN = BEGIN RETURN t.reguse[reg].upbound; END upper; -PROCEDURE set_lower (t: T; reg: Regno; newlow: TIntN.T) = +PROCEDURE set_lower (t: T; reg: Regno; newlow: Target.IntN) = BEGIN t.reguse[reg].lowbound := newlow; END set_lower; -PROCEDURE set_upper (t: T; reg: Regno; newup: TIntN.T) = +PROCEDURE set_upper (t: T; reg: Regno; newup: Target.IntN) = BEGIN t.reguse[reg].upbound := newup; END set_upper; @@ -2531,15 +2532,15 @@ WITH z = t.reguse[i] DO z.stackp := -1; z.last_store := NoStore; - z.upbound := TIntN.Max32; - z.lowbound := TIntN.Min32; + z.upbound := Target.Integer.maxN; + z.lowbound := Target.Integer.minN; z.imm := FALSE; z.non_nil := FALSE; z.locked := FALSE; END; END; - t.rmode := ARRAY FlToInt OF TIntN.T + t.rmode := ARRAY FlToInt OF Target.IntN { TZero, TIntN.x0400, TIntN.x0800, TIntN.x0F00 }; t.lowset_table := NIL; t.highset_table := NIL; @@ -2551,8 +2552,8 @@ t.lowset_table := ImportBitmaskTable (t, "_lowbits"); END; tbl.var := t.lowset_table; - tbl.offset := 0; - tbl.type := Type.Int32; + tbl.mvar_offset := 0; + tbl.mvar_type := Type.Int32; END ImportLowSet; PROCEDURE ImportHighSet (t: T; VAR(*OUT*)tbl: MVar) = @@ -2561,8 +2562,8 @@ t.highset_table := ImportBitmaskTable (t, "_highbits"); END; tbl.var := t.highset_table; - tbl.offset := 0; - tbl.type := Type.Int32; + tbl.mvar_offset := 0; + tbl.mvar_type := Type.Int32; END ImportHighSet; PROCEDURE ImportBitmaskTable (t: T; nm: TEXT): x86Var = @@ -2636,10 +2637,10 @@ IF (NOT TIntN.EQ(r.last_imm, TZero)) THEN wr.OutT (" imm: "); wr.OutT (TIntN.ToText (r.last_imm)); END; - IF (NOT TIntN.EQ(r.lowbound, TIntN.Min32)) THEN + IF (NOT TIntN.EQ(r.lowbound, Target.Integer.minN)) THEN wr.OutT (" lo: "); wr.OutT (TIntN.ToText (r.lowbound)); END; - IF (NOT TIntN.EQ(r.upbound, TIntN.Max32)) THEN + IF (NOT TIntN.EQ(r.upbound, Target.Integer.maxN)) THEN wr.OutT (" hi: "); wr.OutT (TIntN.ToText (r.upbound)); END; IF (r.imm # FALSE) THEN @@ -2656,8 +2657,8 @@ PROCEDURE DebugMVar (READONLY v: MVar; wr: Wrx86.T) = BEGIN wr.OutT ("{ "); wr.VName (v.var); - IF (v.offset # 0) THEN wr.OutT (" offset: "); wr.OutI (v.offset); END; - wr.OutT (" type: "); wr.TName (v.type); + IF (v.mvar_offset # 0) THEN wr.OutT (" offset: "); wr.OutI (v.mvar_offset); END; + wr.OutT (" type: "); wr.TName (v.mvar_type); wr.OutT (" }"); END DebugMVar; Index: Wrx86.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Wrx86.i3,v retrieving revision 1.8 diff -u -r1.8 Wrx86.i3 --- Wrx86.i3 27 Feb 2010 00:49:46 -0000 1.8 +++ Wrx86.i3 27 Feb 2010 12:33:14 -0000 @@ -29,7 +29,7 @@ Lab (i: Label); Tipe (t: TypeUID); Int (i: INTEGER); - TInt (READONLY i: Target.Int); + TInt (READONLY i: Target.IntN); BInt (i: INTEGER); Txt (t: TEXT); OutC (c: CHAR); Index: Wrx86.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Wrx86.m3,v retrieving revision 1.16 diff -u -r1.16 Wrx86.m3 --- Wrx86.m3 27 Feb 2010 00:49:46 -0000 1.16 +++ Wrx86.m3 27 Feb 2010 12:33:14 -0000 @@ -9,7 +9,7 @@ MODULE Wrx86; IMPORT Wr, Thread, Text; -IMPORT M3Buf, M3ID, M3CG, Target, TInt AS TargetInt, TFloat; +IMPORT M3Buf, M3ID, M3CG, TIntN, Target, TFloat; FROM M3CG IMPORT Name, TypeUID; FROM M3CG IMPORT Var, Proc, Label, No_label; @@ -55,7 +55,9 @@ BEGIN OutC (t, '\t'); OutT (t, cmd); - FOR i := 0 TO 14-len DO OutC (t, ' ') END; + FOR i := 0 TO 14-len DO + OutC (t, ' ') + END; OutC (t, ' '); OutC (t, ' '); END Cmd; @@ -63,9 +65,10 @@ PROCEDURE ZName (t: T; n: Name) = BEGIN OutC (t, ' '); - IF (n = M3ID.NoID) - THEN OutC (t, '*'); - ELSE OutN (t, n); + IF (n = M3ID.NoID) THEN + OutC (t, '*'); + ELSE + OutN (t, n); END; END ZName; @@ -130,9 +133,10 @@ PROCEDURE Lab (t: T; i: Label) = BEGIN OutC (t, ' '); - IF (i = No_label) - THEN OutC (t, '*'); - ELSE OutT (t, "L."); OutI (t, i); + IF (i = No_label) THEN + OutC (t, '*'); + ELSE + OutT (t, "L."); OutI (t, i); END; END Lab; @@ -148,13 +152,15 @@ OutI (t, i); END Int; -PROCEDURE TInt (t: T; READONLY i: Target.Int) = +PROCEDURE TInt (t: T; READONLY i: Target.IntN) = VAR - buf : ARRAY [0..BITSIZE (Target.Int)] OF CHAR; - len := TargetInt.ToChars (i, buf); + buf : ARRAY [0..BITSIZE (Target.IntN)] OF CHAR; + len := TIntN.ToChars (i, buf); BEGIN OutC (t, ' '); OutS (t, SUBARRAY (buf, 0, len)); + OutC (t, ' '); + OutT (t, TIntN.ToDiagnosticText(i)); END TInt; PROCEDURE BInt (t: T; i: INTEGER) = @@ -165,12 +171,13 @@ (********* PROCEDURE BInt (t: T; i: INTEGER) = - VAR x := i MOD Target.Byte; - y := i DIV Target.Byte; + VAR x := i MOD TIntN.Byte; + y := i DIV TIntN.Byte; BEGIN - IF (x = 0) - THEN Int (t, y); - ELSE Int (t, y); OutC (t, '+'); OutI (t, x); + IF (x = 0) THEN + Int (t, y); + ELSE + Int (t, y); OutC (t, '+'); OutI (t, x); END; END BInt; ***************) @@ -212,39 +219,42 @@ Wr.Flush (t.wr); END Flush; +PROCEDURE IncLength (t: T; approximateIncrease: CARDINAL) = + BEGIN + INC (t.buf_len, approximateIncrease); + IF (t.buf_len >= 1024) OR (t.buf_len < 0) THEN + Flush (t) + END; + END IncLength; + PROCEDURE OutC (t: T; c: CHAR) = BEGIN M3Buf.PutChar (t.buf, c); - INC (t.buf_len); - IF (t.buf_len >= 1024) THEN Flush (t) END; + IncLength (t, 1); END OutC; PROCEDURE OutT (t: T; txt: TEXT) = BEGIN M3Buf.PutText (t.buf, txt); - INC (t.buf_len, Text.Length (txt)); - IF (t.buf_len >= 1024) THEN Flush (t) END; + IncLength (t, Text.Length (txt)); END OutT; PROCEDURE OutN (t: T; n: Name) = BEGIN M3ID.Put (t.buf, n); - INC (t.buf_len, 10); (* we don't really care if it's accurate *) - IF (t.buf_len >= 1024) THEN Flush (t) END; + IncLength (t, 10); (* This does not have to be accurate. *) END OutN; PROCEDURE OutS (t: T; READONLY buf: ARRAY OF CHAR) = BEGIN M3Buf.PutSub (t.buf, buf); - INC (t.buf_len, NUMBER (buf)); - IF (t.buf_len >= 1024) THEN Flush (t) END; + IncLength (t, NUMBER (buf)); END OutS; PROCEDURE OutI (t: T; i: INTEGER) = BEGIN M3Buf.PutInt (t.buf, i); - INC (t.buf_len, 4); (* we don't really care if it's accurate *) - IF (t.buf_len >= 1024) THEN Flush (t) END; + IncLength (t, 4); (* This does not have to be accurate. *) END OutI;