|
|
@@ -1,11 +1,4 @@
|
|
|
-(*
|
|
|
- BSD 2-Clause License
|
|
|
-
|
|
|
- Copyright (c) 2019-2022, Anton Krotov
|
|
|
- All rights reserved.
|
|
|
-*)
|
|
|
-
|
|
|
-MODULE MSP430;
|
|
|
+MODULE MSP430;
|
|
|
|
|
|
IMPORT IL, LISTS, REG, CHL := CHUNKLISTS, ERRORS, WR := WRITER, HEX,
|
|
|
UTILS, C := CONSOLE, PROG, RTL := MSP430RTL;
|
|
|
@@ -114,1658 +107,1658 @@ VAR
|
|
|
|
|
|
|
|
|
PROCEDURE CheckProcDataSize* (VarSize, RamSize: INTEGER): BOOLEAN;
|
|
|
- RETURN (VarSize + 1) * 2 + StkReserve + RTL.VarSize < RamSize
|
|
|
-END CheckProcDataSize;
|
|
|
+ RETURN (VarSize + 1) * 2 + StkReserve + RTL.VarSize < RamSize
|
|
|
+ END CheckProcDataSize;
|
|
|
|
|
|
|
|
|
PROCEDURE EmitLabel (L: INTEGER);
|
|
|
-VAR
|
|
|
- label: LABEL;
|
|
|
+ VAR
|
|
|
+ label: LABEL;
|
|
|
|
|
|
-BEGIN
|
|
|
- NEW(label);
|
|
|
- label.num := L;
|
|
|
- LISTS.push(CodeList, label)
|
|
|
-END EmitLabel;
|
|
|
+ BEGIN
|
|
|
+ NEW(label);
|
|
|
+ label.num := L;
|
|
|
+ LISTS.push(CodeList, label)
|
|
|
+ END EmitLabel;
|
|
|
|
|
|
|
|
|
PROCEDURE EmitWord (val: INTEGER);
|
|
|
-VAR
|
|
|
- word: WORD;
|
|
|
-
|
|
|
-BEGIN
|
|
|
- IF val < 0 THEN
|
|
|
- ASSERT(val >= -32768);
|
|
|
- val := val MOD 65536
|
|
|
- ELSE
|
|
|
- ASSERT(val <= 65535)
|
|
|
- END;
|
|
|
- NEW(word);
|
|
|
- word.val := val;
|
|
|
- LISTS.push(CodeList, word)
|
|
|
-END EmitWord;
|
|
|
+ VAR
|
|
|
+ word: WORD;
|
|
|
+
|
|
|
+ BEGIN
|
|
|
+ IF val < 0 THEN
|
|
|
+ ASSERT(val >= -32768);
|
|
|
+ val := val MOD 65536
|
|
|
+ ELSE
|
|
|
+ ASSERT(val <= 65535)
|
|
|
+ END;
|
|
|
+ NEW(word);
|
|
|
+ word.val := val;
|
|
|
+ LISTS.push(CodeList, word)
|
|
|
+ END EmitWord;
|
|
|
|
|
|
|
|
|
PROCEDURE EmitJmp (cc, label: INTEGER);
|
|
|
-VAR
|
|
|
- jmp: JMP;
|
|
|
+ VAR
|
|
|
+ jmp: JMP;
|
|
|
|
|
|
-BEGIN
|
|
|
- NEW(jmp);
|
|
|
- jmp.cc := cc;
|
|
|
- jmp.label := label;
|
|
|
- jmp.short := FALSE;
|
|
|
- LISTS.push(CodeList, jmp)
|
|
|
-END EmitJmp;
|
|
|
+ BEGIN
|
|
|
+ NEW(jmp);
|
|
|
+ jmp.cc := cc;
|
|
|
+ jmp.label := label;
|
|
|
+ jmp.short := FALSE;
|
|
|
+ LISTS.push(CodeList, jmp)
|
|
|
+ END EmitJmp;
|
|
|
|
|
|
|
|
|
PROCEDURE EmitCall (label: INTEGER);
|
|
|
-VAR
|
|
|
- call: CALL;
|
|
|
+ VAR
|
|
|
+ call: CALL;
|
|
|
|
|
|
-BEGIN
|
|
|
- NEW(call);
|
|
|
- call.label := label;
|
|
|
- LISTS.push(CodeList, call)
|
|
|
-END EmitCall;
|
|
|
+ BEGIN
|
|
|
+ NEW(call);
|
|
|
+ call.label := label;
|
|
|
+ LISTS.push(CodeList, call)
|
|
|
+ END EmitCall;
|
|
|
|
|
|
|
|
|
PROCEDURE IncStk;
|
|
|
-BEGIN
|
|
|
- INC(StkCnt);
|
|
|
- MaxStkCnt := MAX(StkCnt, MaxStkCnt)
|
|
|
-END IncStk;
|
|
|
+ BEGIN
|
|
|
+ INC(StkCnt);
|
|
|
+ MaxStkCnt := MAX(StkCnt, MaxStkCnt)
|
|
|
+ END IncStk;
|
|
|
|
|
|
|
|
|
PROCEDURE bw (b: BOOLEAN): INTEGER;
|
|
|
- RETURN BW * ORD(b)
|
|
|
-END bw;
|
|
|
+ RETURN BW * ORD(b)
|
|
|
+ END bw;
|
|
|
|
|
|
|
|
|
PROCEDURE src_x (x, Rn: INTEGER): INTEGER;
|
|
|
-VAR
|
|
|
- res: INTEGER;
|
|
|
-
|
|
|
-BEGIN
|
|
|
- IF (x = 0) & ~(Rn IN {PC, SR, CG}) THEN
|
|
|
- res := Rn * 256 + sINDIR
|
|
|
- ELSE
|
|
|
- IdxWords.src := x;
|
|
|
- res := Rn * 256 + sIDX
|
|
|
- END
|
|
|
+ VAR
|
|
|
+ res: INTEGER;
|
|
|
+
|
|
|
+ BEGIN
|
|
|
+ IF (x = 0) & ~(Rn IN {PC, SR, CG}) THEN
|
|
|
+ res := Rn * 256 + sINDIR
|
|
|
+ ELSE
|
|
|
+ IdxWords.src := x;
|
|
|
+ res := Rn * 256 + sIDX
|
|
|
+ END
|
|
|
|
|
|
- RETURN res
|
|
|
-END src_x;
|
|
|
+ RETURN res
|
|
|
+ END src_x;
|
|
|
|
|
|
|
|
|
PROCEDURE dst_x (x, Rn: INTEGER): INTEGER;
|
|
|
-BEGIN
|
|
|
- IdxWords.dst := x
|
|
|
- RETURN Rn + dIDX
|
|
|
-END dst_x;
|
|
|
+ BEGIN
|
|
|
+ IdxWords.dst := x
|
|
|
+ RETURN Rn + dIDX
|
|
|
+ END dst_x;
|
|
|
|
|
|
|
|
|
PROCEDURE indir (Rn: INTEGER): INTEGER;
|
|
|
- RETURN Rn * 256 + sINDIR
|
|
|
-END indir;
|
|
|
+ RETURN Rn * 256 + sINDIR
|
|
|
+ END indir;
|
|
|
|
|
|
|
|
|
PROCEDURE incr (Rn: INTEGER): INTEGER;
|
|
|
- RETURN Rn * 256 + sINCR
|
|
|
-END incr;
|
|
|
+ RETURN Rn * 256 + sINCR
|
|
|
+ END incr;
|
|
|
|
|
|
|
|
|
PROCEDURE imm (x: INTEGER): INTEGER;
|
|
|
-VAR
|
|
|
- res: INTEGER;
|
|
|
-
|
|
|
-BEGIN
|
|
|
- CASE x OF
|
|
|
- | 0: res := CG * 256
|
|
|
- | 1: res := CG * 256 + sIDX
|
|
|
- | 2: res := indir(CG)
|
|
|
- | 4: res := indir(SR)
|
|
|
- | 8: res := incr(SR)
|
|
|
- |-1: res := incr(CG)
|
|
|
- ELSE
|
|
|
- res := incr(PC);
|
|
|
- IdxWords.src := x
|
|
|
- END
|
|
|
+ VAR
|
|
|
+ res: INTEGER;
|
|
|
+
|
|
|
+ BEGIN
|
|
|
+ CASE x OF
|
|
|
+ | 0: res := CG * 256
|
|
|
+ | 1: res := CG * 256 + sIDX
|
|
|
+ | 2: res := indir(CG)
|
|
|
+ | 4: res := indir(SR)
|
|
|
+ | 8: res := incr(SR)
|
|
|
+ |-1: res := incr(CG)
|
|
|
+ ELSE
|
|
|
+ res := incr(PC);
|
|
|
+ IdxWords.src := x
|
|
|
+ END
|
|
|
|
|
|
- RETURN res
|
|
|
-END imm;
|
|
|
+ RETURN res
|
|
|
+ END imm;
|
|
|
|
|
|
|
|
|
PROCEDURE Op2 (op, src, dst: INTEGER);
|
|
|
-BEGIN
|
|
|
- ASSERT(BITS(op) - {6, 12..15} = {});
|
|
|
- ASSERT(BITS(src) - {4, 5, 8..11} = {});
|
|
|
- ASSERT(BITS(dst) - {0..3, 7} = {});
|
|
|
+ BEGIN
|
|
|
+ ASSERT(BITS(op) - {6, 12..15} = {});
|
|
|
+ ASSERT(BITS(src) - {4, 5, 8..11} = {});
|
|
|
+ ASSERT(BITS(dst) - {0..3, 7} = {});
|
|
|
|
|
|
- EmitWord(op + src + dst);
|
|
|
+ EmitWord(op + src + dst);
|
|
|
|
|
|
- IF IdxWords.src # NOWORD THEN
|
|
|
- EmitWord(IdxWords.src);
|
|
|
- IdxWords.src := NOWORD
|
|
|
- END;
|
|
|
+ IF IdxWords.src # NOWORD THEN
|
|
|
+ EmitWord(IdxWords.src);
|
|
|
+ IdxWords.src := NOWORD
|
|
|
+ END;
|
|
|
|
|
|
- IF IdxWords.dst # NOWORD THEN
|
|
|
- EmitWord(IdxWords.dst);
|
|
|
- IdxWords.dst := NOWORD
|
|
|
- END
|
|
|
-END Op2;
|
|
|
+ IF IdxWords.dst # NOWORD THEN
|
|
|
+ EmitWord(IdxWords.dst);
|
|
|
+ IdxWords.dst := NOWORD
|
|
|
+ END
|
|
|
+ END Op2;
|
|
|
|
|
|
|
|
|
PROCEDURE Op1 (op, reg, As: INTEGER);
|
|
|
-BEGIN
|
|
|
- EmitWord(op + reg + As)
|
|
|
-END Op1;
|
|
|
+ BEGIN
|
|
|
+ EmitWord(op + reg + As)
|
|
|
+ END Op1;
|
|
|
|
|
|
|
|
|
PROCEDURE MovRR (src, dst: INTEGER);
|
|
|
-BEGIN
|
|
|
- Op2(opMOV, src * 256, dst)
|
|
|
-END MovRR;
|
|
|
+ BEGIN
|
|
|
+ Op2(opMOV, src * 256, dst)
|
|
|
+ END MovRR;
|
|
|
|
|
|
|
|
|
PROCEDURE PushImm (imm: INTEGER);
|
|
|
-BEGIN
|
|
|
- imm := UTILS.Long(imm);
|
|
|
- CASE imm OF
|
|
|
- | 0: Op1(opPUSH, CG, sREG)
|
|
|
- | 1: Op1(opPUSH, CG, sIDX)
|
|
|
- | 2: Op1(opPUSH, CG, sINDIR)
|
|
|
- |-1: Op1(opPUSH, CG, sINCR)
|
|
|
- ELSE
|
|
|
- Op1(opPUSH, PC, sINCR);
|
|
|
- EmitWord(imm)
|
|
|
- END;
|
|
|
- IncStk
|
|
|
-END PushImm;
|
|
|
+ BEGIN
|
|
|
+ imm := UTILS.Long(imm);
|
|
|
+ CASE imm OF
|
|
|
+ | 0: Op1(opPUSH, CG, sREG)
|
|
|
+ | 1: Op1(opPUSH, CG, sIDX)
|
|
|
+ | 2: Op1(opPUSH, CG, sINDIR)
|
|
|
+ |-1: Op1(opPUSH, CG, sINCR)
|
|
|
+ ELSE
|
|
|
+ Op1(opPUSH, PC, sINCR);
|
|
|
+ EmitWord(imm)
|
|
|
+ END;
|
|
|
+ IncStk
|
|
|
+ END PushImm;
|
|
|
|
|
|
|
|
|
PROCEDURE PutWord (word: INTEGER; VAR adr: INTEGER);
|
|
|
-BEGIN
|
|
|
- ASSERT(~ODD(adr));
|
|
|
- ASSERT((0 <= word) & (word <= 65535));
|
|
|
- mem[adr] := word MOD 256;
|
|
|
- mem[adr + 1] := word DIV 256;
|
|
|
- INC(adr, 2)
|
|
|
-END PutWord;
|
|
|
+ BEGIN
|
|
|
+ ASSERT(~ODD(adr));
|
|
|
+ ASSERT((0 <= word) & (word <= 65535));
|
|
|
+ mem[adr] := word MOD 256;
|
|
|
+ mem[adr + 1] := word DIV 256;
|
|
|
+ INC(adr, 2)
|
|
|
+ END PutWord;
|
|
|
|
|
|
|
|
|
PROCEDURE NewLabel (): INTEGER;
|
|
|
-BEGIN
|
|
|
- CHL.PushInt(Labels, 0)
|
|
|
- RETURN IL.NewLabel()
|
|
|
-END NewLabel;
|
|
|
+ BEGIN
|
|
|
+ CHL.PushInt(Labels, 0)
|
|
|
+ RETURN IL.NewLabel()
|
|
|
+ END NewLabel;
|
|
|
|
|
|
|
|
|
PROCEDURE LabelOffs (n: INTEGER): INTEGER;
|
|
|
- RETURN CHL.GetInt(Labels, n)
|
|
|
-END LabelOffs;
|
|
|
+ RETURN CHL.GetInt(Labels, n)
|
|
|
+ END LabelOffs;
|
|
|
|
|
|
|
|
|
PROCEDURE Fixup (CodeAdr, IntVectorSize: INTEGER): INTEGER;
|
|
|
-VAR
|
|
|
- cmd: ANYCODE;
|
|
|
- adr: INTEGER;
|
|
|
- offset: INTEGER;
|
|
|
- diff: INTEGER;
|
|
|
- cc: INTEGER;
|
|
|
- shorted: BOOLEAN;
|
|
|
-
|
|
|
-BEGIN
|
|
|
- REPEAT
|
|
|
- shorted := FALSE;
|
|
|
- offset := CodeAdr DIV 2;
|
|
|
-
|
|
|
- cmd := CodeList.first(ANYCODE);
|
|
|
- WHILE cmd # NIL DO
|
|
|
- cmd.offset := offset;
|
|
|
- CASE cmd OF
|
|
|
- |LABEL: CHL.SetInt(Labels, cmd.num, offset)
|
|
|
- |JMP: INC(offset);
|
|
|
- IF ~cmd.short THEN
|
|
|
- INC(offset);
|
|
|
- IF cmd.cc # opJMP THEN
|
|
|
- INC(offset)
|
|
|
+ VAR
|
|
|
+ cmd: ANYCODE;
|
|
|
+ adr: INTEGER;
|
|
|
+ offset: INTEGER;
|
|
|
+ diff: INTEGER;
|
|
|
+ cc: INTEGER;
|
|
|
+ shorted: BOOLEAN;
|
|
|
+
|
|
|
+ BEGIN
|
|
|
+ REPEAT
|
|
|
+ shorted := FALSE;
|
|
|
+ offset := CodeAdr DIV 2;
|
|
|
+
|
|
|
+ cmd := CodeList.first(ANYCODE);
|
|
|
+ WHILE cmd # NIL DO
|
|
|
+ cmd.offset := offset;
|
|
|
+ CASE cmd OF
|
|
|
+ |LABEL: CHL.SetInt(Labels, cmd.num, offset)
|
|
|
+ |JMP: INC(offset);
|
|
|
+ IF ~cmd.short THEN
|
|
|
+ INC(offset);
|
|
|
+ IF cmd.cc # opJMP THEN
|
|
|
+ INC(offset)
|
|
|
+ END
|
|
|
END
|
|
|
- END
|
|
|
|
|
|
- |CALL: INC(offset, 2)
|
|
|
- |WORD: INC(offset)
|
|
|
- END;
|
|
|
- cmd := cmd.next(ANYCODE)
|
|
|
- END;
|
|
|
-
|
|
|
- cmd := CodeList.first(ANYCODE);
|
|
|
- WHILE cmd # NIL DO
|
|
|
- IF (cmd IS JMP) & ~cmd(JMP).short THEN
|
|
|
- diff := LabelOffs(cmd(JMP).label) - cmd.offset - 1;
|
|
|
- IF ABS(diff) <= 512 THEN
|
|
|
- cmd(JMP).short := TRUE;
|
|
|
- shorted := TRUE
|
|
|
- END
|
|
|
+ |CALL: INC(offset, 2)
|
|
|
+ |WORD: INC(offset)
|
|
|
+ END;
|
|
|
+ cmd := cmd.next(ANYCODE)
|
|
|
END;
|
|
|
- cmd := cmd.next(ANYCODE)
|
|
|
- END
|
|
|
|
|
|
- UNTIL ~shorted;
|
|
|
+ cmd := CodeList.first(ANYCODE);
|
|
|
+ WHILE cmd # NIL DO
|
|
|
+ IF (cmd IS JMP) & ~cmd(JMP).short THEN
|
|
|
+ diff := LabelOffs(cmd(JMP).label) - cmd.offset - 1;
|
|
|
+ IF ABS(diff) <= 512 THEN
|
|
|
+ cmd(JMP).short := TRUE;
|
|
|
+ shorted := TRUE
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ cmd := cmd.next(ANYCODE)
|
|
|
+ END
|
|
|
|
|
|
- IF offset * 2 > 10000H - IntVectorSize THEN
|
|
|
- ERRORS.Error(203)
|
|
|
- END;
|
|
|
+ UNTIL ~shorted;
|
|
|
|
|
|
- adr := CodeAdr;
|
|
|
- cmd := CodeList.first(ANYCODE);
|
|
|
- WHILE cmd # NIL DO
|
|
|
- CASE cmd OF
|
|
|
- |LABEL:
|
|
|
-
|
|
|
- |JMP: IF ~cmd.short THEN
|
|
|
- CASE cmd.cc OF
|
|
|
- |opJNE: cc := opJEQ
|
|
|
- |opJEQ: cc := opJNE
|
|
|
- |opJNC: cc := opJC
|
|
|
- |opJC: cc := opJNC
|
|
|
- |opJGE: cc := opJL
|
|
|
- |opJL: cc := opJGE
|
|
|
- |opJMP: cc := opJMP
|
|
|
- END;
|
|
|
+ IF offset * 2 > 10000H - IntVectorSize THEN
|
|
|
+ ERRORS.Error(203)
|
|
|
+ END;
|
|
|
|
|
|
- IF cc # opJMP THEN
|
|
|
- PutWord(cc + 2, adr) (* jcc L *)
|
|
|
- END;
|
|
|
+ adr := CodeAdr;
|
|
|
+ cmd := CodeList.first(ANYCODE);
|
|
|
+ WHILE cmd # NIL DO
|
|
|
+ CASE cmd OF
|
|
|
+ |LABEL:
|
|
|
+
|
|
|
+ |JMP: IF ~cmd.short THEN
|
|
|
+ CASE cmd.cc OF
|
|
|
+ |opJNE: cc := opJEQ
|
|
|
+ |opJEQ: cc := opJNE
|
|
|
+ |opJNC: cc := opJC
|
|
|
+ |opJC: cc := opJNC
|
|
|
+ |opJGE: cc := opJL
|
|
|
+ |opJL: cc := opJGE
|
|
|
+ |opJMP: cc := opJMP
|
|
|
+ END;
|
|
|
+
|
|
|
+ IF cc # opJMP THEN
|
|
|
+ PutWord(cc + 2, adr) (* jcc L *)
|
|
|
+ END;
|
|
|
+
|
|
|
+ PutWord(4030H, adr); (* MOV @PC+, PC *)
|
|
|
+ PutWord(LabelOffs(cmd.label) * 2, adr)
|
|
|
+ (* L: *)
|
|
|
+ ELSE
|
|
|
+ diff := LabelOffs(cmd.label) - cmd.offset - 1;
|
|
|
+ ASSERT((-512 <= diff) & (diff <= 511));
|
|
|
+ PutWord(cmd.cc + diff MOD 1024, adr)
|
|
|
+ END
|
|
|
|
|
|
- PutWord(4030H, adr); (* MOV @PC+, PC *)
|
|
|
+ |CALL: PutWord(12B0H, adr); (* CALL @PC+ *)
|
|
|
PutWord(LabelOffs(cmd.label) * 2, adr)
|
|
|
- (* L: *)
|
|
|
- ELSE
|
|
|
- diff := LabelOffs(cmd.label) - cmd.offset - 1;
|
|
|
- ASSERT((-512 <= diff) & (diff <= 511));
|
|
|
- PutWord(cmd.cc + diff MOD 1024, adr)
|
|
|
- END
|
|
|
|
|
|
- |CALL: PutWord(12B0H, adr); (* CALL @PC+ *)
|
|
|
- PutWord(LabelOffs(cmd.label) * 2, adr)
|
|
|
+ |WORD: PutWord(cmd.val, adr)
|
|
|
|
|
|
- |WORD: PutWord(cmd.val, adr)
|
|
|
-
|
|
|
- END;
|
|
|
- cmd := cmd.next(ANYCODE)
|
|
|
- END
|
|
|
+ END;
|
|
|
+ cmd := cmd.next(ANYCODE)
|
|
|
+ END
|
|
|
|
|
|
- RETURN adr - CodeAdr
|
|
|
-END Fixup;
|
|
|
+ RETURN adr - CodeAdr
|
|
|
+ END Fixup;
|
|
|
|
|
|
|
|
|
PROCEDURE Push (reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- Op1(opPUSH, reg, sREG);
|
|
|
- IncStk
|
|
|
-END Push;
|
|
|
+ BEGIN
|
|
|
+ Op1(opPUSH, reg, sREG);
|
|
|
+ IncStk
|
|
|
+ END Push;
|
|
|
|
|
|
|
|
|
PROCEDURE Pop (reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- Op2(opMOV, incr(SP), reg);
|
|
|
- DEC(StkCnt)
|
|
|
-END Pop;
|
|
|
+ BEGIN
|
|
|
+ Op2(opMOV, incr(SP), reg);
|
|
|
+ DEC(StkCnt)
|
|
|
+ END Pop;
|
|
|
|
|
|
|
|
|
PROCEDURE Test (reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- Op2(opCMP, imm(0), reg)
|
|
|
-END Test;
|
|
|
+ BEGIN
|
|
|
+ Op2(opCMP, imm(0), reg)
|
|
|
+ END Test;
|
|
|
|
|
|
|
|
|
PROCEDURE Clear (reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- Op2(opMOV, imm(0), reg)
|
|
|
-END Clear;
|
|
|
+ BEGIN
|
|
|
+ Op2(opMOV, imm(0), reg)
|
|
|
+ END Clear;
|
|
|
|
|
|
|
|
|
PROCEDURE mov (dst, src: INTEGER);
|
|
|
-BEGIN
|
|
|
- MovRR(src, dst)
|
|
|
-END mov;
|
|
|
+ BEGIN
|
|
|
+ MovRR(src, dst)
|
|
|
+ END mov;
|
|
|
|
|
|
|
|
|
PROCEDURE xchg (reg1, reg2: INTEGER);
|
|
|
-BEGIN
|
|
|
- Push(reg1);
|
|
|
- mov(reg1, reg2);
|
|
|
- Pop(reg2)
|
|
|
-END xchg;
|
|
|
+ BEGIN
|
|
|
+ Push(reg1);
|
|
|
+ mov(reg1, reg2);
|
|
|
+ Pop(reg2)
|
|
|
+ END xchg;
|
|
|
|
|
|
|
|
|
PROCEDURE Reloc (section: INTEGER);
|
|
|
-VAR
|
|
|
- reloc: RELOC;
|
|
|
+ VAR
|
|
|
+ reloc: RELOC;
|
|
|
|
|
|
-BEGIN
|
|
|
- NEW(reloc);
|
|
|
- reloc.section := section;
|
|
|
- reloc.WordPtr := CodeList.last(WORD);
|
|
|
- LISTS.push(RelList, reloc)
|
|
|
-END Reloc;
|
|
|
+ BEGIN
|
|
|
+ NEW(reloc);
|
|
|
+ reloc.section := section;
|
|
|
+ reloc.WordPtr := CodeList.last(WORD);
|
|
|
+ LISTS.push(RelList, reloc)
|
|
|
+ END Reloc;
|
|
|
|
|
|
|
|
|
PROCEDURE CallRTL (proc, params: INTEGER);
|
|
|
-BEGIN
|
|
|
- IncStk;
|
|
|
- DEC(StkCnt);
|
|
|
- EmitCall(RTL.rtl[proc].label);
|
|
|
- RTL.Used(proc);
|
|
|
- IF params > 0 THEN
|
|
|
- Op2(opADD, imm(params * 2), SP);
|
|
|
- DEC(StkCnt, params)
|
|
|
- END
|
|
|
-END CallRTL;
|
|
|
+ BEGIN
|
|
|
+ IncStk;
|
|
|
+ DEC(StkCnt);
|
|
|
+ EmitCall(RTL.rtl[proc].label);
|
|
|
+ RTL.Used(proc);
|
|
|
+ IF params > 0 THEN
|
|
|
+ Op2(opADD, imm(params * 2), SP);
|
|
|
+ DEC(StkCnt, params)
|
|
|
+ END
|
|
|
+ END CallRTL;
|
|
|
|
|
|
|
|
|
PROCEDURE UnOp (VAR reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- REG.UnOp(R, reg)
|
|
|
-END UnOp;
|
|
|
+ BEGIN
|
|
|
+ REG.UnOp(R, reg)
|
|
|
+ END UnOp;
|
|
|
|
|
|
|
|
|
PROCEDURE BinOp (VAR reg1, reg2: INTEGER);
|
|
|
-BEGIN
|
|
|
- REG.BinOp(R, reg1, reg2)
|
|
|
-END BinOp;
|
|
|
+ BEGIN
|
|
|
+ REG.BinOp(R, reg1, reg2)
|
|
|
+ END BinOp;
|
|
|
|
|
|
|
|
|
PROCEDURE GetRegA;
|
|
|
-BEGIN
|
|
|
- ASSERT(REG.GetReg(R, ACC))
|
|
|
-END GetRegA;
|
|
|
+ BEGIN
|
|
|
+ ASSERT(REG.GetReg(R, ACC))
|
|
|
+ END GetRegA;
|
|
|
|
|
|
|
|
|
PROCEDURE drop;
|
|
|
-BEGIN
|
|
|
- REG.Drop(R)
|
|
|
-END drop;
|
|
|
+ BEGIN
|
|
|
+ REG.Drop(R)
|
|
|
+ END drop;
|
|
|
|
|
|
|
|
|
PROCEDURE GetAnyReg (): INTEGER;
|
|
|
- RETURN REG.GetAnyReg(R)
|
|
|
-END GetAnyReg;
|
|
|
+ RETURN REG.GetAnyReg(R)
|
|
|
+ END GetAnyReg;
|
|
|
|
|
|
|
|
|
PROCEDURE PushAll (NumberOfParameters: INTEGER);
|
|
|
-BEGIN
|
|
|
- REG.PushAll(R);
|
|
|
- DEC(R.pushed, NumberOfParameters)
|
|
|
-END PushAll;
|
|
|
+ BEGIN
|
|
|
+ REG.PushAll(R);
|
|
|
+ DEC(R.pushed, NumberOfParameters)
|
|
|
+ END PushAll;
|
|
|
|
|
|
|
|
|
PROCEDURE PushAll_1;
|
|
|
-BEGIN
|
|
|
- REG.PushAll_1(R)
|
|
|
-END PushAll_1;
|
|
|
+ BEGIN
|
|
|
+ REG.PushAll_1(R)
|
|
|
+ END PushAll_1;
|
|
|
|
|
|
|
|
|
PROCEDURE cond (op: INTEGER): INTEGER;
|
|
|
-VAR
|
|
|
- res: INTEGER;
|
|
|
+ VAR
|
|
|
+ res: INTEGER;
|
|
|
|
|
|
-BEGIN
|
|
|
- CASE op OF
|
|
|
- |IL.opGT, IL.opGTC: res := jg
|
|
|
- |IL.opGE, IL.opGEC: res := jge
|
|
|
- |IL.opLT, IL.opLTC: res := jl
|
|
|
- |IL.opLE, IL.opLEC: res := jle
|
|
|
- |IL.opEQ, IL.opEQC: res := je
|
|
|
- |IL.opNE, IL.opNEC: res := jne
|
|
|
- END
|
|
|
+ BEGIN
|
|
|
+ CASE op OF
|
|
|
+ |IL.opGT, IL.opGTC: res := jg
|
|
|
+ |IL.opGE, IL.opGEC: res := jge
|
|
|
+ |IL.opLT, IL.opLTC: res := jl
|
|
|
+ |IL.opLE, IL.opLEC: res := jle
|
|
|
+ |IL.opEQ, IL.opEQC: res := je
|
|
|
+ |IL.opNE, IL.opNEC: res := jne
|
|
|
+ END
|
|
|
|
|
|
- RETURN res
|
|
|
-END cond;
|
|
|
+ RETURN res
|
|
|
+ END cond;
|
|
|
|
|
|
|
|
|
PROCEDURE jcc (cc, label: INTEGER);
|
|
|
-VAR
|
|
|
- L: INTEGER;
|
|
|
-
|
|
|
-BEGIN
|
|
|
- CASE cc OF
|
|
|
- |jne:
|
|
|
- EmitJmp(opJNE, label)
|
|
|
- |je:
|
|
|
- EmitJmp(opJEQ, label)
|
|
|
- |jge:
|
|
|
- EmitJmp(opJGE, label)
|
|
|
- |jl:
|
|
|
- EmitJmp(opJL, label)
|
|
|
- |jle:
|
|
|
- EmitJmp(opJL, label);
|
|
|
- EmitJmp(opJEQ, label)
|
|
|
- |jg:
|
|
|
- L := NewLabel();
|
|
|
- EmitJmp(opJEQ, L);
|
|
|
- EmitJmp(opJGE, label);
|
|
|
- EmitLabel(L)
|
|
|
- |jb:
|
|
|
- EmitJmp(opJNC, label)
|
|
|
- END
|
|
|
-END jcc;
|
|
|
+ VAR
|
|
|
+ L: INTEGER;
|
|
|
+
|
|
|
+ BEGIN
|
|
|
+ CASE cc OF
|
|
|
+ |jne:
|
|
|
+ EmitJmp(opJNE, label)
|
|
|
+ |je:
|
|
|
+ EmitJmp(opJEQ, label)
|
|
|
+ |jge:
|
|
|
+ EmitJmp(opJGE, label)
|
|
|
+ |jl:
|
|
|
+ EmitJmp(opJL, label)
|
|
|
+ |jle:
|
|
|
+ EmitJmp(opJL, label);
|
|
|
+ EmitJmp(opJEQ, label)
|
|
|
+ |jg:
|
|
|
+ L := NewLabel();
|
|
|
+ EmitJmp(opJEQ, L);
|
|
|
+ EmitJmp(opJGE, label);
|
|
|
+ EmitLabel(L)
|
|
|
+ |jb:
|
|
|
+ EmitJmp(opJNC, label)
|
|
|
+ END
|
|
|
+ END jcc;
|
|
|
|
|
|
|
|
|
PROCEDURE setcc (cc, reg: INTEGER);
|
|
|
-VAR
|
|
|
- L: INTEGER;
|
|
|
+ VAR
|
|
|
+ L: INTEGER;
|
|
|
|
|
|
-BEGIN
|
|
|
- L := NewLabel();
|
|
|
- Op2(opMOV, imm(1), reg);
|
|
|
- jcc(cc, L);
|
|
|
- Clear(reg);
|
|
|
- EmitLabel(L)
|
|
|
-END setcc;
|
|
|
+ BEGIN
|
|
|
+ L := NewLabel();
|
|
|
+ Op2(opMOV, imm(1), reg);
|
|
|
+ jcc(cc, L);
|
|
|
+ Clear(reg);
|
|
|
+ EmitLabel(L)
|
|
|
+ END setcc;
|
|
|
|
|
|
|
|
|
PROCEDURE Shift2 (op, reg, n: INTEGER);
|
|
|
-VAR
|
|
|
- reg2: INTEGER;
|
|
|
-
|
|
|
-BEGIN
|
|
|
- IF n >= 8 THEN
|
|
|
- CASE op OF
|
|
|
- |IL.opASR2: Op1(opSWPB, reg, sREG); Op1(opSXT, reg, sREG)
|
|
|
- |IL.opROR2: Op1(opSWPB, reg, sREG)
|
|
|
- |IL.opLSL2: Op1(opSWPB, reg, sREG); Op2(opBIC, imm(255), reg)
|
|
|
- |IL.opLSR2: Op2(opBIC, imm(255), reg); Op1(opSWPB, reg, sREG)
|
|
|
+ VAR
|
|
|
+ reg2: INTEGER;
|
|
|
+
|
|
|
+ BEGIN
|
|
|
+ IF n >= 8 THEN
|
|
|
+ CASE op OF
|
|
|
+ |IL.opASR2: Op1(opSWPB, reg, sREG); Op1(opSXT, reg, sREG)
|
|
|
+ |IL.opROR2: Op1(opSWPB, reg, sREG)
|
|
|
+ |IL.opLSL2: Op1(opSWPB, reg, sREG); Op2(opBIC, imm(255), reg)
|
|
|
+ |IL.opLSR2: Op2(opBIC, imm(255), reg); Op1(opSWPB, reg, sREG)
|
|
|
+ END;
|
|
|
+ DEC(n, 8)
|
|
|
END;
|
|
|
- DEC(n, 8)
|
|
|
- END;
|
|
|
|
|
|
- IF (op = IL.opROR2) & (n > 0) THEN
|
|
|
- reg2 := GetAnyReg();
|
|
|
- MovRR(reg, reg2)
|
|
|
- ELSE
|
|
|
- reg2 := -1
|
|
|
- END;
|
|
|
+ IF (op = IL.opROR2) & (n > 0) THEN
|
|
|
+ reg2 := GetAnyReg();
|
|
|
+ MovRR(reg, reg2)
|
|
|
+ ELSE
|
|
|
+ reg2 := -1
|
|
|
+ END;
|
|
|
|
|
|
- WHILE n > 0 DO
|
|
|
- CASE op OF
|
|
|
- |IL.opASR2: Op1(opRRA, reg, sREG)
|
|
|
- |IL.opROR2: Op1(opRRC, reg2, sREG); Op1(opRRC, reg, sREG)
|
|
|
- |IL.opLSL2: Op2(opADD, reg * 256, reg)
|
|
|
- |IL.opLSR2: Op2(opBIC, imm(1), SR); Op1(opRRC, reg, sREG)
|
|
|
+ WHILE n > 0 DO
|
|
|
+ CASE op OF
|
|
|
+ |IL.opASR2: Op1(opRRA, reg, sREG)
|
|
|
+ |IL.opROR2: Op1(opRRC, reg2, sREG); Op1(opRRC, reg, sREG)
|
|
|
+ |IL.opLSL2: Op2(opADD, reg * 256, reg)
|
|
|
+ |IL.opLSR2: Op2(opBIC, imm(1), SR); Op1(opRRC, reg, sREG)
|
|
|
+ END;
|
|
|
+ DEC(n)
|
|
|
END;
|
|
|
- DEC(n)
|
|
|
- END;
|
|
|
|
|
|
- IF reg2 # -1 THEN
|
|
|
- drop
|
|
|
- END
|
|
|
+ IF reg2 # -1 THEN
|
|
|
+ drop
|
|
|
+ END
|
|
|
|
|
|
-END Shift2;
|
|
|
+ END Shift2;
|
|
|
|
|
|
|
|
|
PROCEDURE Neg (reg: INTEGER);
|
|
|
-BEGIN
|
|
|
- Op2(opXOR, imm(-1), reg);
|
|
|
- Op2(opADD, imm(1), reg)
|
|
|
-END Neg;
|
|
|
+ BEGIN
|
|
|
+ Op2(opXOR, imm(-1), reg);
|
|
|
+ Op2(opADD, imm(1), reg)
|
|
|
+ END Neg;
|
|
|
|
|
|
|
|
|
PROCEDURE LocalOffset (offset: INTEGER): INTEGER;
|
|
|
- RETURN (offset + StkCnt - ORD(offset > 0)) * 2
|
|
|
-END LocalOffset;
|
|
|
+ RETURN (offset + StkCnt - ORD(offset > 0)) * 2
|
|
|
+ END LocalOffset;
|
|
|
|
|
|
|
|
|
PROCEDURE LocalDst (offset: INTEGER): INTEGER;
|
|
|
- RETURN dst_x(LocalOffset(offset), SP)
|
|
|
-END LocalDst;
|
|
|
+ RETURN dst_x(LocalOffset(offset), SP)
|
|
|
+ END LocalDst;
|
|
|
|
|
|
|
|
|
PROCEDURE LocalSrc (offset: INTEGER): INTEGER;
|
|
|
- RETURN src_x(LocalOffset(offset), SP)
|
|
|
-END LocalSrc;
|
|
|
+ RETURN src_x(LocalOffset(offset), SP)
|
|
|
+ END LocalSrc;
|
|
|
|
|
|
|
|
|
PROCEDURE translate (chk_stk: BOOLEAN);
|
|
|
-VAR
|
|
|
- cmd, next: COMMAND;
|
|
|
+ VAR
|
|
|
+ cmd, next: COMMAND;
|
|
|
|
|
|
- opcode, param1, param2, L, a, n, c1, c2: INTEGER;
|
|
|
+ opcode, param1, param2, L, a, n, c1, c2: INTEGER;
|
|
|
|
|
|
- reg1, reg2: INTEGER;
|
|
|
+ reg1, reg2: INTEGER;
|
|
|
|
|
|
- cc: INTEGER;
|
|
|
+ cc: INTEGER;
|
|
|
|
|
|
- word: WORD;
|
|
|
+ word: WORD;
|
|
|
|
|
|
-BEGIN
|
|
|
- cmd := IL.codes.commands.first(COMMAND);
|
|
|
+ BEGIN
|
|
|
+ cmd := IL.codes.commands.first(COMMAND);
|
|
|
|
|
|
- WHILE cmd # NIL DO
|
|
|
+ WHILE cmd # NIL DO
|
|
|
|
|
|
- param1 := cmd.param1;
|
|
|
- param2 := cmd.param2;
|
|
|
+ param1 := cmd.param1;
|
|
|
+ param2 := cmd.param2;
|
|
|
|
|
|
- opcode := cmd.opcode;
|
|
|
+ opcode := cmd.opcode;
|
|
|
|
|
|
- CASE opcode OF
|
|
|
- |IL.opJMP:
|
|
|
- EmitJmp(opJMP, param1)
|
|
|
+ CASE opcode OF
|
|
|
+ |IL.opJMP:
|
|
|
+ EmitJmp(opJMP, param1)
|
|
|
|
|
|
- |IL.opCALL:
|
|
|
- IncStk;
|
|
|
- DEC(StkCnt);
|
|
|
- EmitCall(param1)
|
|
|
+ |IL.opCALL:
|
|
|
+ IncStk;
|
|
|
+ DEC(StkCnt);
|
|
|
+ EmitCall(param1)
|
|
|
|
|
|
- |IL.opCALLP:
|
|
|
- IncStk;
|
|
|
- DEC(StkCnt);
|
|
|
- UnOp(reg1);
|
|
|
- Op1(opCALL, reg1, sREG);
|
|
|
- drop;
|
|
|
- ASSERT(R.top = -1)
|
|
|
+ |IL.opCALLP:
|
|
|
+ IncStk;
|
|
|
+ DEC(StkCnt);
|
|
|
+ UnOp(reg1);
|
|
|
+ Op1(opCALL, reg1, sREG);
|
|
|
+ drop;
|
|
|
+ ASSERT(R.top = -1)
|
|
|
|
|
|
- |IL.opPRECALL:
|
|
|
- PushAll(0)
|
|
|
+ |IL.opPRECALL:
|
|
|
+ PushAll(0)
|
|
|
|
|
|
- |IL.opLABEL:
|
|
|
- EmitLabel(param1)
|
|
|
+ |IL.opLABEL:
|
|
|
+ EmitLabel(param1)
|
|
|
|
|
|
- |IL.opSADR_PARAM:
|
|
|
- Op1(opPUSH, PC, sINCR);
|
|
|
- IncStk;
|
|
|
- EmitWord(param2);
|
|
|
- Reloc(RDATA)
|
|
|
-
|
|
|
- |IL.opERR:
|
|
|
- CallRTL(RTL._error, 2)
|
|
|
-
|
|
|
- |IL.opPUSHC:
|
|
|
- PushImm(param2)
|
|
|
-
|
|
|
- |IL.opONERR:
|
|
|
- DEC(StkCnt);
|
|
|
- EmitWord(0C232H); (* BIC #8, SR; DINT *)
|
|
|
- EmitWord(4303H); (* MOV R3, R3; NOP *)
|
|
|
- PushImm(param2);
|
|
|
- EmitJmp(opJMP, param1)
|
|
|
-
|
|
|
- |IL.opLEAVEC:
|
|
|
- Pop(PC)
|
|
|
-
|
|
|
- |IL.opENTER:
|
|
|
- ASSERT(R.top = -1);
|
|
|
- EmitLabel(param1);
|
|
|
- n := param2 MOD 65536;
|
|
|
- param2 := param2 DIV 65536;
|
|
|
- StkCnt := 0;
|
|
|
- IF chk_stk THEN
|
|
|
- L := NewLabel();
|
|
|
- Op2(opMOV, SP * 256, R4);
|
|
|
- Op2(opSUB, HP * 256, R4);
|
|
|
- Op2(opCMP, imm(StkReserve), R4);
|
|
|
- word := CodeList.last(WORD);
|
|
|
- jcc(jge, L);
|
|
|
+ |IL.opSADR_PARAM:
|
|
|
+ Op1(opPUSH, PC, sINCR);
|
|
|
+ IncStk;
|
|
|
+ EmitWord(param2);
|
|
|
+ Reloc(RDATA)
|
|
|
+
|
|
|
+ |IL.opERR:
|
|
|
+ CallRTL(RTL._error, 2)
|
|
|
+
|
|
|
+ |IL.opPUSHC:
|
|
|
+ PushImm(param2)
|
|
|
+
|
|
|
+ |IL.opONERR:
|
|
|
DEC(StkCnt);
|
|
|
EmitWord(0C232H); (* BIC #8, SR; DINT *)
|
|
|
EmitWord(4303H); (* MOV R3, R3; NOP *)
|
|
|
- PushImm(n);
|
|
|
- EmitJmp(opJMP, cmd.param3);
|
|
|
- EmitLabel(L)
|
|
|
- END;
|
|
|
+ PushImm(param2);
|
|
|
+ EmitJmp(opJMP, param1)
|
|
|
+
|
|
|
+ |IL.opLEAVEC:
|
|
|
+ Pop(PC)
|
|
|
+
|
|
|
+ |IL.opENTER:
|
|
|
+ ASSERT(R.top = -1);
|
|
|
+ EmitLabel(param1);
|
|
|
+ n := param2 MOD 65536;
|
|
|
+ param2 := param2 DIV 65536;
|
|
|
+ StkCnt := 0;
|
|
|
+ IF chk_stk THEN
|
|
|
+ L := NewLabel();
|
|
|
+ Op2(opMOV, SP * 256, R4);
|
|
|
+ Op2(opSUB, HP * 256, R4);
|
|
|
+ Op2(opCMP, imm(StkReserve), R4);
|
|
|
+ word := CodeList.last(WORD);
|
|
|
+ jcc(jge, L);
|
|
|
+ DEC(StkCnt);
|
|
|
+ EmitWord(0C232H); (* BIC #8, SR; DINT *)
|
|
|
+ EmitWord(4303H); (* MOV R3, R3; NOP *)
|
|
|
+ PushImm(n);
|
|
|
+ EmitJmp(opJMP, cmd.param3);
|
|
|
+ EmitLabel(L)
|
|
|
+ END;
|
|
|
|
|
|
- IF param2 > 8 THEN
|
|
|
- Op2(opMOV, imm(param2), R4);
|
|
|
- L := NewLabel();
|
|
|
- EmitLabel(L);
|
|
|
- Push(CG);
|
|
|
- Op2(opSUB, imm(1), R4);
|
|
|
- jcc(jne, L)
|
|
|
- ELSE
|
|
|
- FOR n := 1 TO param2 DO
|
|
|
- Push(CG)
|
|
|
- END
|
|
|
- END;
|
|
|
- StkCnt := param2;
|
|
|
- MaxStkCnt := StkCnt
|
|
|
+ IF param2 > 8 THEN
|
|
|
+ Op2(opMOV, imm(param2), R4);
|
|
|
+ L := NewLabel();
|
|
|
+ EmitLabel(L);
|
|
|
+ Push(CG);
|
|
|
+ Op2(opSUB, imm(1), R4);
|
|
|
+ jcc(jne, L)
|
|
|
+ ELSE
|
|
|
+ FOR n := 1 TO param2 DO
|
|
|
+ Push(CG)
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ StkCnt := param2;
|
|
|
+ MaxStkCnt := StkCnt
|
|
|
|
|
|
- |IL.opLEAVE, IL.opLEAVER:
|
|
|
- ASSERT(param2 = 0);
|
|
|
- IF opcode = IL.opLEAVER THEN
|
|
|
- UnOp(reg1);
|
|
|
- IF reg1 # ACC THEN
|
|
|
- mov(ACC, reg1)
|
|
|
+ |IL.opLEAVE, IL.opLEAVER:
|
|
|
+ ASSERT(param2 = 0);
|
|
|
+ IF opcode = IL.opLEAVER THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ IF reg1 # ACC THEN
|
|
|
+ mov(ACC, reg1)
|
|
|
+ END;
|
|
|
+ drop
|
|
|
END;
|
|
|
- drop
|
|
|
- END;
|
|
|
- ASSERT(R.top = -1);
|
|
|
- ASSERT(StkCnt = param1);
|
|
|
- IF chk_stk THEN
|
|
|
- INC(word.val, MaxStkCnt * 2)
|
|
|
- END;
|
|
|
- IF param1 > 0 THEN
|
|
|
- Op2(opADD, imm(param1 * 2), SP)
|
|
|
- END;
|
|
|
- Pop(PC)
|
|
|
+ ASSERT(R.top = -1);
|
|
|
+ ASSERT(StkCnt = param1);
|
|
|
+ IF chk_stk THEN
|
|
|
+ INC(word.val, MaxStkCnt * 2)
|
|
|
+ END;
|
|
|
+ IF param1 > 0 THEN
|
|
|
+ Op2(opADD, imm(param1 * 2), SP)
|
|
|
+ END;
|
|
|
+ Pop(PC)
|
|
|
|
|
|
- |IL.opRES:
|
|
|
- ASSERT(R.top = -1);
|
|
|
- GetRegA
|
|
|
+ |IL.opRES:
|
|
|
+ ASSERT(R.top = -1);
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opCLEANUP:
|
|
|
- IF param2 # 0 THEN
|
|
|
- Op2(opADD, imm(param2 * 2), SP);
|
|
|
- DEC(StkCnt, param2)
|
|
|
- END
|
|
|
+ |IL.opCLEANUP:
|
|
|
+ IF param2 # 0 THEN
|
|
|
+ Op2(opADD, imm(param2 * 2), SP);
|
|
|
+ DEC(StkCnt, param2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opCONST:
|
|
|
- next := cmd.next(COMMAND);
|
|
|
- IF next.opcode = IL.opCONST THEN
|
|
|
- c1 := param2;
|
|
|
- c2 := next.param2;
|
|
|
- next := next.next(COMMAND);
|
|
|
- IF (next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVE16) OR (next.opcode = IL.opSAVE8) THEN
|
|
|
- Op2(opMOV + bw(next.opcode = IL.opSAVE8), imm(c1), dst_x(c2, SR));
|
|
|
+ |IL.opCONST:
|
|
|
+ next := cmd.next(COMMAND);
|
|
|
+ IF next.opcode = IL.opCONST THEN
|
|
|
+ c1 := param2;
|
|
|
+ c2 := next.param2;
|
|
|
+ next := next.next(COMMAND);
|
|
|
+ IF (next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVE16) OR (next.opcode = IL.opSAVE8) THEN
|
|
|
+ Op2(opMOV + bw(next.opcode = IL.opSAVE8), imm(c1), dst_x(c2, SR));
|
|
|
+ cmd := next
|
|
|
+ ELSE
|
|
|
+ Op2(opMOV, imm(param2), GetAnyReg())
|
|
|
+ END
|
|
|
+ ELSIF (next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVE16) OR (next.opcode = IL.opSAVE8) THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opMOV + bw(next.opcode = IL.opSAVE8), reg1 * 256, dst_x(param2, SR));
|
|
|
+ drop;
|
|
|
cmd := next
|
|
|
ELSE
|
|
|
Op2(opMOV, imm(param2), GetAnyReg())
|
|
|
END
|
|
|
- ELSIF (next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVE16) OR (next.opcode = IL.opSAVE8) THEN
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opMOV + bw(next.opcode = IL.opSAVE8), reg1 * 256, dst_x(param2, SR));
|
|
|
- drop;
|
|
|
- cmd := next
|
|
|
- ELSE
|
|
|
- Op2(opMOV, imm(param2), GetAnyReg())
|
|
|
- END
|
|
|
|
|
|
- |IL.opSADR:
|
|
|
- Op2(opMOV, incr(PC), GetAnyReg());
|
|
|
- EmitWord(param2);
|
|
|
- Reloc(RDATA)
|
|
|
-
|
|
|
- |IL.opGADR:
|
|
|
- Op2(opMOV, incr(PC), GetAnyReg());
|
|
|
- EmitWord(param2);
|
|
|
- Reloc(RBSS)
|
|
|
-
|
|
|
- |IL.opLADR:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- n := LocalOffset(param2);
|
|
|
- Op2(opMOV, SP * 256, reg1);
|
|
|
- IF n # 0 THEN
|
|
|
- Op2(opADD, imm(n), reg1)
|
|
|
- END
|
|
|
+ |IL.opSADR:
|
|
|
+ Op2(opMOV, incr(PC), GetAnyReg());
|
|
|
+ EmitWord(param2);
|
|
|
+ Reloc(RDATA)
|
|
|
+
|
|
|
+ |IL.opGADR:
|
|
|
+ Op2(opMOV, incr(PC), GetAnyReg());
|
|
|
+ EmitWord(param2);
|
|
|
+ Reloc(RBSS)
|
|
|
+
|
|
|
+ |IL.opLADR:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ n := LocalOffset(param2);
|
|
|
+ Op2(opMOV, SP * 256, reg1);
|
|
|
+ IF n # 0 THEN
|
|
|
+ Op2(opADD, imm(n), reg1)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opLLOAD8:
|
|
|
- Op2(opMOV + BW, LocalSrc(param2), GetAnyReg())
|
|
|
+ |IL.opLLOAD8:
|
|
|
+ Op2(opMOV + BW, LocalSrc(param2), GetAnyReg())
|
|
|
|
|
|
- |IL.opLLOAD16, IL.opVADR:
|
|
|
- Op2(opMOV, LocalSrc(param2), GetAnyReg())
|
|
|
+ |IL.opLLOAD16, IL.opVADR:
|
|
|
+ Op2(opMOV, LocalSrc(param2), GetAnyReg())
|
|
|
|
|
|
- |IL.opGLOAD8:
|
|
|
- Op2(opMOV + BW, src_x(param2, SR), GetAnyReg());
|
|
|
- Reloc(RBSS)
|
|
|
+ |IL.opGLOAD8:
|
|
|
+ Op2(opMOV + BW, src_x(param2, SR), GetAnyReg());
|
|
|
+ Reloc(RBSS)
|
|
|
|
|
|
- |IL.opGLOAD16:
|
|
|
- Op2(opMOV, src_x(param2, SR), GetAnyReg());
|
|
|
- Reloc(RBSS)
|
|
|
+ |IL.opGLOAD16:
|
|
|
+ Op2(opMOV, src_x(param2, SR), GetAnyReg());
|
|
|
+ Reloc(RBSS)
|
|
|
|
|
|
- |IL.opLOAD8:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opMOV + BW, indir(reg1), reg1)
|
|
|
+ |IL.opLOAD8:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opMOV + BW, indir(reg1), reg1)
|
|
|
|
|
|
- |IL.opLOAD16:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opMOV, indir(reg1), reg1)
|
|
|
+ |IL.opLOAD16:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opMOV, indir(reg1), reg1)
|
|
|
|
|
|
- |IL.opVLOAD8:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- Op2(opMOV, LocalSrc(param2), reg1);
|
|
|
- Op2(opMOV + BW, indir(reg1), reg1)
|
|
|
+ |IL.opVLOAD8:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ Op2(opMOV, LocalSrc(param2), reg1);
|
|
|
+ Op2(opMOV + BW, indir(reg1), reg1)
|
|
|
|
|
|
- |IL.opVLOAD16:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- Op2(opMOV, LocalSrc(param2), reg1);
|
|
|
- Op2(opMOV, indir(reg1), reg1)
|
|
|
+ |IL.opVLOAD16:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ Op2(opMOV, LocalSrc(param2), reg1);
|
|
|
+ Op2(opMOV, indir(reg1), reg1)
|
|
|
|
|
|
- |IL.opSAVE, IL.opSAVE16:
|
|
|
- BinOp(reg2, reg1);
|
|
|
- Op2(opMOV, reg2 * 256, dst_x(0, reg1));
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opSAVE, IL.opSAVE16:
|
|
|
+ BinOp(reg2, reg1);
|
|
|
+ Op2(opMOV, reg2 * 256, dst_x(0, reg1));
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opSAVE8:
|
|
|
- BinOp(reg2, reg1);
|
|
|
- Op2(opMOV + BW, reg2 * 256, dst_x(0, reg1));
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opSAVE8:
|
|
|
+ BinOp(reg2, reg1);
|
|
|
+ Op2(opMOV + BW, reg2 * 256, dst_x(0, reg1));
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opSAVE8C:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opMOV + BW, imm(param2), dst_x(0, reg1));
|
|
|
- drop
|
|
|
+ |IL.opSAVE8C:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opMOV + BW, imm(param2), dst_x(0, reg1));
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opSAVE16C, IL.opSAVEC:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opMOV, imm(param2), dst_x(0, reg1));
|
|
|
- drop
|
|
|
+ |IL.opSAVE16C, IL.opSAVEC:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opMOV, imm(param2), dst_x(0, reg1));
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opUMINUS:
|
|
|
- UnOp(reg1);
|
|
|
- Neg(reg1)
|
|
|
+ |IL.opUMINUS:
|
|
|
+ UnOp(reg1);
|
|
|
+ Neg(reg1)
|
|
|
|
|
|
- |IL.opADD:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- Op2(opADD, reg2 * 256, reg1);
|
|
|
- drop
|
|
|
+ |IL.opADD:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ Op2(opADD, reg2 * 256, reg1);
|
|
|
+ drop
|
|
|
+
|
|
|
+ |IL.opADDC:
|
|
|
+ IF param2 # 0 THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opADD, imm(param2), reg1)
|
|
|
+ END
|
|
|
+
|
|
|
+ |IL.opSUB:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ Op2(opSUB, reg2 * 256, reg1);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opADDC:
|
|
|
- IF param2 # 0 THEN
|
|
|
+ |IL.opSUBR, IL.opSUBL:
|
|
|
UnOp(reg1);
|
|
|
- Op2(opADD, imm(param2), reg1)
|
|
|
- END
|
|
|
+ IF param2 # 0 THEN
|
|
|
+ Op2(opSUB, imm(param2), reg1)
|
|
|
+ END;
|
|
|
+ IF opcode = IL.opSUBL THEN
|
|
|
+ Neg(reg1)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opSUB:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- Op2(opSUB, reg2 * 256, reg1);
|
|
|
- drop
|
|
|
+ |IL.opLADR_SAVEC:
|
|
|
+ Op2(opMOV, imm(param2), LocalDst(param1))
|
|
|
|
|
|
- |IL.opSUBR, IL.opSUBL:
|
|
|
- UnOp(reg1);
|
|
|
- IF param2 # 0 THEN
|
|
|
- Op2(opSUB, imm(param2), reg1)
|
|
|
- END;
|
|
|
- IF opcode = IL.opSUBL THEN
|
|
|
- Neg(reg1)
|
|
|
- END
|
|
|
+ |IL.opLADR_SAVE:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opMOV, reg1 * 256, LocalDst(param2));
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opLADR_SAVEC:
|
|
|
- Op2(opMOV, imm(param2), LocalDst(param1))
|
|
|
+ |IL.opGADR_SAVEC:
|
|
|
+ Op2(opMOV, imm(param2), dst_x(param1, SR));
|
|
|
+ Reloc(RBSS)
|
|
|
|
|
|
- |IL.opLADR_SAVE:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opMOV, reg1 * 256, LocalDst(param2));
|
|
|
- drop
|
|
|
+ |IL.opCONST_PARAM:
|
|
|
+ PushImm(param2)
|
|
|
|
|
|
- |IL.opGADR_SAVEC:
|
|
|
- Op2(opMOV, imm(param2), dst_x(param1, SR));
|
|
|
- Reloc(RBSS)
|
|
|
+ |IL.opPARAM:
|
|
|
+ IF param2 = 1 THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ Push(reg1);
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ ASSERT(R.top + 1 <= param2);
|
|
|
+ PushAll(param2)
|
|
|
+ END
|
|
|
+
|
|
|
+ |IL.opEQ..IL.opGE,
|
|
|
+ IL.opEQC..IL.opGEC:
|
|
|
+
|
|
|
+ IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ Op2(opCMP, reg2 * 256, reg1);
|
|
|
+ drop
|
|
|
+ ELSE
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opCMP, imm(param2), reg1)
|
|
|
+ END;
|
|
|
+
|
|
|
+ drop;
|
|
|
+ cc := cond(opcode);
|
|
|
+ next := cmd.next(COMMAND);
|
|
|
+
|
|
|
+ IF next.opcode = IL.opJNZ THEN
|
|
|
+ jcc(cc, next.param1);
|
|
|
+ cmd := next
|
|
|
+ ELSIF next.opcode = IL.opJZ THEN
|
|
|
+ jcc(ORD(BITS(cc) / {0}), next.param1);
|
|
|
+ cmd := next
|
|
|
+ ELSE
|
|
|
+ setcc(cc, GetAnyReg())
|
|
|
+ END
|
|
|
+
|
|
|
+ |IL.opNOP, IL.opAND, IL.opOR:
|
|
|
|
|
|
- |IL.opCONST_PARAM:
|
|
|
- PushImm(param2)
|
|
|
+ |IL.opCODE:
|
|
|
+ EmitWord(param2)
|
|
|
|
|
|
- |IL.opPARAM:
|
|
|
- IF param2 = 1 THEN
|
|
|
+ |IL.opDROP:
|
|
|
UnOp(reg1);
|
|
|
- Push(reg1);
|
|
|
drop
|
|
|
- ELSE
|
|
|
- ASSERT(R.top + 1 <= param2);
|
|
|
- PushAll(param2)
|
|
|
- END
|
|
|
|
|
|
- |IL.opEQ..IL.opGE,
|
|
|
- IL.opEQC..IL.opGEC:
|
|
|
+ |IL.opJNZ1:
|
|
|
+ UnOp(reg1);
|
|
|
+ Test(reg1);
|
|
|
+ jcc(jne, param1)
|
|
|
|
|
|
- IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN
|
|
|
- BinOp(reg1, reg2);
|
|
|
- Op2(opCMP, reg2 * 256, reg1);
|
|
|
+ |IL.opJG:
|
|
|
+ UnOp(reg1);
|
|
|
+ Test(reg1);
|
|
|
+ jcc(jg, param1)
|
|
|
+
|
|
|
+ |IL.opJNZ:
|
|
|
+ UnOp(reg1);
|
|
|
+ Test(reg1);
|
|
|
+ jcc(jne, param1);
|
|
|
drop
|
|
|
- ELSE
|
|
|
+
|
|
|
+ |IL.opJZ:
|
|
|
UnOp(reg1);
|
|
|
- Op2(opCMP, imm(param2), reg1)
|
|
|
- END;
|
|
|
+ Test(reg1);
|
|
|
+ jcc(je, param1);
|
|
|
+ drop
|
|
|
|
|
|
- drop;
|
|
|
- cc := cond(opcode);
|
|
|
- next := cmd.next(COMMAND);
|
|
|
-
|
|
|
- IF next.opcode = IL.opJNZ THEN
|
|
|
- jcc(cc, next.param1);
|
|
|
- cmd := next
|
|
|
- ELSIF next.opcode = IL.opJZ THEN
|
|
|
- jcc(ORD(BITS(cc) / {0}), next.param1);
|
|
|
- cmd := next
|
|
|
- ELSE
|
|
|
- setcc(cc, GetAnyReg())
|
|
|
- END
|
|
|
+ |IL.opNOT:
|
|
|
+ UnOp(reg1);
|
|
|
+ Test(reg1);
|
|
|
+ setcc(je, reg1)
|
|
|
|
|
|
- |IL.opNOP, IL.opAND, IL.opOR:
|
|
|
+ |IL.opORD:
|
|
|
+ UnOp(reg1);
|
|
|
+ Test(reg1);
|
|
|
+ setcc(jne, reg1)
|
|
|
|
|
|
- |IL.opCODE:
|
|
|
- EmitWord(param2)
|
|
|
+ |IL.opGET:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ drop;
|
|
|
+ drop;
|
|
|
+ Op2(opMOV + bw(param2 = 1), indir(reg1), dst_x(0, reg2))
|
|
|
|
|
|
- |IL.opDROP:
|
|
|
- UnOp(reg1);
|
|
|
- drop
|
|
|
+ |IL.opGETC:
|
|
|
+ UnOp(reg2);
|
|
|
+ drop;
|
|
|
+ Op2(opMOV + bw(param2 = 1), src_x(param1, SR), dst_x(0, reg2))
|
|
|
|
|
|
- |IL.opJNZ1:
|
|
|
- UnOp(reg1);
|
|
|
- Test(reg1);
|
|
|
- jcc(jne, param1)
|
|
|
+ |IL.opCHKIDX:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opCMP, imm(param2), reg1);
|
|
|
+ jcc(jb, param1)
|
|
|
|
|
|
- |IL.opJG:
|
|
|
- UnOp(reg1);
|
|
|
- Test(reg1);
|
|
|
- jcc(jg, param1)
|
|
|
+ |IL.opCHKIDX2:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ IF param2 # -1 THEN
|
|
|
+ Op2(opCMP, reg1 * 256, reg2);
|
|
|
+ jcc(jb, param1)
|
|
|
+ END;
|
|
|
+ INCL(R.regs, reg1);
|
|
|
+ DEC(R.top);
|
|
|
+ R.stk[R.top] := reg2
|
|
|
|
|
|
- |IL.opJNZ:
|
|
|
- UnOp(reg1);
|
|
|
- Test(reg1);
|
|
|
- jcc(jne, param1);
|
|
|
- drop
|
|
|
+ |IL.opINCC, IL.opINCCB:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opADD + bw(opcode = IL.opINCCB), imm(param2), dst_x(0, reg1));
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opJZ:
|
|
|
- UnOp(reg1);
|
|
|
- Test(reg1);
|
|
|
- jcc(je, param1);
|
|
|
- drop
|
|
|
+ |IL.opDECCB:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opSUB + BW, imm(param2), dst_x(0, reg1));
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opNOT:
|
|
|
- UnOp(reg1);
|
|
|
- Test(reg1);
|
|
|
- setcc(je, reg1)
|
|
|
-
|
|
|
- |IL.opORD:
|
|
|
- UnOp(reg1);
|
|
|
- Test(reg1);
|
|
|
- setcc(jne, reg1)
|
|
|
-
|
|
|
- |IL.opGET:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- drop;
|
|
|
- drop;
|
|
|
- Op2(opMOV + bw(param2 = 1), indir(reg1), dst_x(0, reg2))
|
|
|
-
|
|
|
- |IL.opGETC:
|
|
|
- UnOp(reg2);
|
|
|
- drop;
|
|
|
- Op2(opMOV + bw(param2 = 1), src_x(param1, SR), dst_x(0, reg2))
|
|
|
-
|
|
|
- |IL.opCHKIDX:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opCMP, imm(param2), reg1);
|
|
|
- jcc(jb, param1)
|
|
|
-
|
|
|
- |IL.opCHKIDX2:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- IF param2 # -1 THEN
|
|
|
- Op2(opCMP, reg1 * 256, reg2);
|
|
|
- jcc(jb, param1)
|
|
|
- END;
|
|
|
- INCL(R.regs, reg1);
|
|
|
- DEC(R.top);
|
|
|
- R.stk[R.top] := reg2
|
|
|
+ |IL.opINC, IL.opINCB:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ Op2(opADD + bw(opcode = IL.opINCB), reg1 * 256, dst_x(0, reg2));
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opINCC, IL.opINCCB:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opADD + bw(opcode = IL.opINCCB), imm(param2), dst_x(0, reg1));
|
|
|
- drop
|
|
|
+ |IL.opDEC, IL.opDECB:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ Op2(opSUB + bw(opcode = IL.opDECB), reg1 * 256, dst_x(0, reg2));
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opDECCB:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opSUB + BW, imm(param2), dst_x(0, reg1));
|
|
|
- drop
|
|
|
+ |IL.opLADR_INCC, IL.opLADR_INCCB:
|
|
|
+ Op2(opADD + bw(opcode = IL.opLADR_INCCB), imm(param2), LocalDst(param1))
|
|
|
|
|
|
- |IL.opINC, IL.opINCB:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- Op2(opADD + bw(opcode = IL.opINCB), reg1 * 256, dst_x(0, reg2));
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opLADR_DECCB:
|
|
|
+ Op2(opSUB + BW, imm(param2), LocalDst(param1))
|
|
|
|
|
|
- |IL.opDEC, IL.opDECB:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- Op2(opSUB + bw(opcode = IL.opDECB), reg1 * 256, dst_x(0, reg2));
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opLADR_INC, IL.opLADR_INCB:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opADD + bw(opcode = IL.opLADR_INCB), reg1 * 256, LocalDst(param2));
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opLADR_INCC, IL.opLADR_INCCB:
|
|
|
- Op2(opADD + bw(opcode = IL.opLADR_INCCB), imm(param2), LocalDst(param1))
|
|
|
+ |IL.opLADR_DEC, IL.opLADR_DECB:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opSUB + bw(opcode = IL.opLADR_DECB), reg1 * 256, LocalDst(param2));
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opLADR_DECCB:
|
|
|
- Op2(opSUB + BW, imm(param2), LocalDst(param1))
|
|
|
+ |IL.opPUSHT:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opMOV, src_x(-2, reg1), GetAnyReg())
|
|
|
+
|
|
|
+ |IL.opISREC:
|
|
|
+ PushAll(2);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._guardrec, 3);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opIS:
|
|
|
+ PushAll(1);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._is, 2);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opTYPEGR:
|
|
|
+ PushAll(1);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._guardrec, 2);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opTYPEGP:
|
|
|
+ UnOp(reg1);
|
|
|
+ PushAll(0);
|
|
|
+ Push(reg1);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._guard, 2);
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opLADR_INC, IL.opLADR_INCB:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opADD + bw(opcode = IL.opLADR_INCB), reg1 * 256, LocalDst(param2));
|
|
|
- drop
|
|
|
+ |IL.opTYPEGD:
|
|
|
+ UnOp(reg1);
|
|
|
+ PushAll(0);
|
|
|
+ Op1(opPUSH, reg1, sIDX);
|
|
|
+ IncStk;
|
|
|
+ EmitWord(-2);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._guardrec, 2);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opMULS:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ Op2(opAND, reg2 * 256, reg1);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opLADR_DEC, IL.opLADR_DECB:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opSUB + bw(opcode = IL.opLADR_DECB), reg1 * 256, LocalDst(param2));
|
|
|
- drop
|
|
|
+ |IL.opMULSC:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opAND, imm(param2), reg1)
|
|
|
|
|
|
- |IL.opPUSHT:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opMOV, src_x(-2, reg1), GetAnyReg())
|
|
|
-
|
|
|
- |IL.opISREC:
|
|
|
- PushAll(2);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._guardrec, 3);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opIS:
|
|
|
- PushAll(1);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._is, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opTYPEGR:
|
|
|
- PushAll(1);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._guardrec, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opTYPEGP:
|
|
|
- UnOp(reg1);
|
|
|
- PushAll(0);
|
|
|
- Push(reg1);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._guard, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opTYPEGD:
|
|
|
- UnOp(reg1);
|
|
|
- PushAll(0);
|
|
|
- Op1(opPUSH, reg1, sIDX);
|
|
|
- IncStk;
|
|
|
- EmitWord(-2);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._guardrec, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opMULS:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- Op2(opAND, reg2 * 256, reg1);
|
|
|
- drop
|
|
|
+ |IL.opDIVS:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ Op2(opXOR, reg2 * 256, reg1);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opMULSC:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opAND, imm(param2), reg1)
|
|
|
+ |IL.opDIVSC:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opXOR, imm(param2), reg1)
|
|
|
|
|
|
- |IL.opDIVS:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- Op2(opXOR, reg2 * 256, reg1);
|
|
|
- drop
|
|
|
+ |IL.opADDS:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ Op2(opBIS, reg2 * 256, reg1);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opDIVSC:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opXOR, imm(param2), reg1)
|
|
|
+ |IL.opSUBS:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ Op2(opBIC, reg2 * 256, reg1);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opADDS:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- Op2(opBIS, reg2 * 256, reg1);
|
|
|
- drop
|
|
|
+ |IL.opADDSC:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opBIS, imm(param2), reg1)
|
|
|
|
|
|
- |IL.opSUBS:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- Op2(opBIC, reg2 * 256, reg1);
|
|
|
- drop
|
|
|
+ |IL.opSUBSL:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opXOR, imm(-1), reg1);
|
|
|
+ Op2(opAND, imm(param2), reg1)
|
|
|
|
|
|
- |IL.opADDSC:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opBIS, imm(param2), reg1)
|
|
|
-
|
|
|
- |IL.opSUBSL:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opXOR, imm(-1), reg1);
|
|
|
- Op2(opAND, imm(param2), reg1)
|
|
|
-
|
|
|
- |IL.opSUBSR:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opBIC, imm(param2), reg1)
|
|
|
-
|
|
|
- |IL.opUMINS:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opXOR, imm(-1), reg1)
|
|
|
-
|
|
|
- |IL.opLENGTH:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(RTL._length, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opMAX,IL.opMIN:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- Op2(opCMP, reg2 * 256, reg1);
|
|
|
- IF opcode = IL.opMIN THEN
|
|
|
- cc := opJL + 1
|
|
|
- ELSE
|
|
|
- cc := opJGE + 1
|
|
|
- END;
|
|
|
- EmitWord(cc); (* jge/jl L *)
|
|
|
- MovRR(reg2, reg1);
|
|
|
- (* L: *)
|
|
|
- drop
|
|
|
+ |IL.opSUBSR:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opBIC, imm(param2), reg1)
|
|
|
|
|
|
- |IL.opMAXC, IL.opMINC:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opCMP, imm(param2), reg1);
|
|
|
- L := NewLabel();
|
|
|
- IF opcode = IL.opMINC THEN
|
|
|
- cc := jl
|
|
|
- ELSE
|
|
|
- cc := jge
|
|
|
- END;
|
|
|
- jcc(cc, L);
|
|
|
- Op2(opMOV, imm(param2), reg1);
|
|
|
- EmitLabel(L)
|
|
|
+ |IL.opUMINS:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opXOR, imm(-1), reg1)
|
|
|
|
|
|
- |IL.opSWITCH:
|
|
|
- UnOp(reg1);
|
|
|
- IF param2 = 0 THEN
|
|
|
- reg2 := ACC
|
|
|
- ELSE
|
|
|
- reg2 := R5
|
|
|
- END;
|
|
|
- IF reg1 # reg2 THEN
|
|
|
- ASSERT(REG.GetReg(R, reg2));
|
|
|
- ASSERT(REG.Exchange(R, reg1, reg2));
|
|
|
+ |IL.opLENGTH:
|
|
|
+ PushAll(2);
|
|
|
+ CallRTL(RTL._length, 2);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opMAX,IL.opMIN:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ Op2(opCMP, reg2 * 256, reg1);
|
|
|
+ IF opcode = IL.opMIN THEN
|
|
|
+ cc := opJL + 1
|
|
|
+ ELSE
|
|
|
+ cc := opJGE + 1
|
|
|
+ END;
|
|
|
+ EmitWord(cc); (* jge/jl L *)
|
|
|
+ MovRR(reg2, reg1);
|
|
|
+ (* L: *)
|
|
|
drop
|
|
|
- END;
|
|
|
- drop
|
|
|
|
|
|
- |IL.opENDSW:
|
|
|
+ |IL.opMAXC, IL.opMINC:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opCMP, imm(param2), reg1);
|
|
|
+ L := NewLabel();
|
|
|
+ IF opcode = IL.opMINC THEN
|
|
|
+ cc := jl
|
|
|
+ ELSE
|
|
|
+ cc := jge
|
|
|
+ END;
|
|
|
+ jcc(cc, L);
|
|
|
+ Op2(opMOV, imm(param2), reg1);
|
|
|
+ EmitLabel(L)
|
|
|
+
|
|
|
+ |IL.opSWITCH:
|
|
|
+ UnOp(reg1);
|
|
|
+ IF param2 = 0 THEN
|
|
|
+ reg2 := ACC
|
|
|
+ ELSE
|
|
|
+ reg2 := R5
|
|
|
+ END;
|
|
|
+ IF reg1 # reg2 THEN
|
|
|
+ ASSERT(REG.GetReg(R, reg2));
|
|
|
+ ASSERT(REG.Exchange(R, reg1, reg2));
|
|
|
+ drop
|
|
|
+ END;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opCASEL:
|
|
|
- Op2(opCMP, imm(param1), ACC);
|
|
|
- jcc(jl, param2)
|
|
|
+ |IL.opENDSW:
|
|
|
|
|
|
- |IL.opCASER:
|
|
|
- Op2(opCMP, imm(param1), ACC);
|
|
|
- jcc(jg, param2)
|
|
|
+ |IL.opCASEL:
|
|
|
+ Op2(opCMP, imm(param1), ACC);
|
|
|
+ jcc(jl, param2)
|
|
|
|
|
|
- |IL.opCASELR:
|
|
|
- Op2(opCMP, imm(param1), ACC);
|
|
|
- IF param2 = cmd.param3 THEN
|
|
|
- jcc(jne, param2)
|
|
|
- ELSE
|
|
|
- jcc(jl, param2);
|
|
|
- jcc(jg, cmd.param3)
|
|
|
- END
|
|
|
+ |IL.opCASER:
|
|
|
+ Op2(opCMP, imm(param1), ACC);
|
|
|
+ jcc(jg, param2)
|
|
|
|
|
|
- |IL.opSBOOL:
|
|
|
- BinOp(reg2, reg1);
|
|
|
- Test(reg2);
|
|
|
- setcc(jne, reg2);
|
|
|
- Op2(opMOV + BW, reg2 * 256, dst_x(0, reg1));
|
|
|
- drop;
|
|
|
- drop
|
|
|
+ |IL.opCASELR:
|
|
|
+ Op2(opCMP, imm(param1), ACC);
|
|
|
+ IF param2 = cmd.param3 THEN
|
|
|
+ jcc(jne, param2)
|
|
|
+ ELSE
|
|
|
+ jcc(jl, param2);
|
|
|
+ jcc(jg, cmd.param3)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opSBOOLC:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opMOV + BW, imm(param2), dst_x(0, reg1));
|
|
|
- drop
|
|
|
+ |IL.opSBOOL:
|
|
|
+ BinOp(reg2, reg1);
|
|
|
+ Test(reg2);
|
|
|
+ setcc(jne, reg2);
|
|
|
+ Op2(opMOV + BW, reg2 * 256, dst_x(0, reg1));
|
|
|
+ drop;
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opEQS .. IL.opGES:
|
|
|
- PushAll(4);
|
|
|
- PushImm((opcode - IL.opEQS) * 12);
|
|
|
- CallRTL(RTL._strcmp, 5);
|
|
|
- GetRegA
|
|
|
+ |IL.opSBOOLC:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opMOV + BW, imm(param2), dst_x(0, reg1));
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opLEN:
|
|
|
- UnOp(reg1);
|
|
|
- drop;
|
|
|
- EXCL(R.regs, reg1);
|
|
|
+ |IL.opEQS .. IL.opGES:
|
|
|
+ PushAll(4);
|
|
|
+ PushImm((opcode - IL.opEQS) * 12);
|
|
|
+ CallRTL(RTL._strcmp, 5);
|
|
|
+ GetRegA
|
|
|
|
|
|
- WHILE param2 > 0 DO
|
|
|
- UnOp(reg2);
|
|
|
+ |IL.opLEN:
|
|
|
+ UnOp(reg1);
|
|
|
drop;
|
|
|
- DEC(param2)
|
|
|
- END;
|
|
|
+ EXCL(R.regs, reg1);
|
|
|
|
|
|
- INCL(R.regs, reg1);
|
|
|
- ASSERT(REG.GetReg(R, reg1))
|
|
|
+ WHILE param2 > 0 DO
|
|
|
+ UnOp(reg2);
|
|
|
+ drop;
|
|
|
+ DEC(param2)
|
|
|
+ END;
|
|
|
|
|
|
- |IL.opLSL, IL.opASR, IL.opROR, IL.opLSR:
|
|
|
- PushAll(2);
|
|
|
- CASE opcode OF
|
|
|
- |IL.opLSL: CallRTL(RTL._lsl, 2)
|
|
|
- |IL.opASR: CallRTL(RTL._asr, 2)
|
|
|
- |IL.opROR: CallRTL(RTL._ror, 2)
|
|
|
- |IL.opLSR: CallRTL(RTL._lsr, 2)
|
|
|
- END;
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opLSL1, IL.opASR1, IL.opROR1, IL.opLSR1:
|
|
|
- UnOp(reg1);
|
|
|
- PushAll_1;
|
|
|
- PushImm(param2);
|
|
|
- Push(reg1);
|
|
|
- drop;
|
|
|
- CASE opcode OF
|
|
|
- |IL.opLSL1: CallRTL(RTL._lsl, 2)
|
|
|
- |IL.opASR1: CallRTL(RTL._asr, 2)
|
|
|
- |IL.opROR1: CallRTL(RTL._ror, 2)
|
|
|
- |IL.opLSR1: CallRTL(RTL._lsr, 2)
|
|
|
- END;
|
|
|
- GetRegA
|
|
|
+ INCL(R.regs, reg1);
|
|
|
+ ASSERT(REG.GetReg(R, reg1))
|
|
|
+
|
|
|
+ |IL.opLSL, IL.opASR, IL.opROR, IL.opLSR:
|
|
|
+ PushAll(2);
|
|
|
+ CASE opcode OF
|
|
|
+ |IL.opLSL: CallRTL(RTL._lsl, 2)
|
|
|
+ |IL.opASR: CallRTL(RTL._asr, 2)
|
|
|
+ |IL.opROR: CallRTL(RTL._ror, 2)
|
|
|
+ |IL.opLSR: CallRTL(RTL._lsr, 2)
|
|
|
+ END;
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2:
|
|
|
- param2 := param2 MOD 16;
|
|
|
- IF param2 # 0 THEN
|
|
|
+ |IL.opLSL1, IL.opASR1, IL.opROR1, IL.opLSR1:
|
|
|
UnOp(reg1);
|
|
|
- Shift2(opcode, reg1, param2)
|
|
|
- END
|
|
|
+ PushAll_1;
|
|
|
+ PushImm(param2);
|
|
|
+ Push(reg1);
|
|
|
+ drop;
|
|
|
+ CASE opcode OF
|
|
|
+ |IL.opLSL1: CallRTL(RTL._lsl, 2)
|
|
|
+ |IL.opASR1: CallRTL(RTL._asr, 2)
|
|
|
+ |IL.opROR1: CallRTL(RTL._ror, 2)
|
|
|
+ |IL.opLSR1: CallRTL(RTL._lsr, 2)
|
|
|
+ END;
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opMUL:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(RTL._mul, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opMULC:
|
|
|
- UnOp(reg1);
|
|
|
-
|
|
|
- a := param2;
|
|
|
- IF a > 1 THEN
|
|
|
- n := UTILS.Log2(a)
|
|
|
- ELSIF a < -1 THEN
|
|
|
- n := UTILS.Log2(-a)
|
|
|
- ELSE
|
|
|
- n := -1
|
|
|
- END;
|
|
|
+ |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2:
|
|
|
+ param2 := param2 MOD 16;
|
|
|
+ IF param2 # 0 THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ Shift2(opcode, reg1, param2)
|
|
|
+ END
|
|
|
|
|
|
- IF a = 1 THEN
|
|
|
+ |IL.opMUL:
|
|
|
+ PushAll(2);
|
|
|
+ CallRTL(RTL._mul, 2);
|
|
|
+ GetRegA
|
|
|
|
|
|
- ELSIF a = -1 THEN
|
|
|
- Neg(reg1)
|
|
|
- ELSIF a = 0 THEN
|
|
|
- Clear(reg1)
|
|
|
- ELSE
|
|
|
- IF n > 0 THEN
|
|
|
- IF a < 0 THEN
|
|
|
- Neg(reg1)
|
|
|
- END;
|
|
|
- Shift2(IL.opLSL2, reg1, n)
|
|
|
+ |IL.opMULC:
|
|
|
+ UnOp(reg1);
|
|
|
+
|
|
|
+ a := param2;
|
|
|
+ IF a > 1 THEN
|
|
|
+ n := UTILS.Log2(a)
|
|
|
+ ELSIF a < -1 THEN
|
|
|
+ n := UTILS.Log2(-a)
|
|
|
+ ELSE
|
|
|
+ n := -1
|
|
|
+ END;
|
|
|
+
|
|
|
+ IF a = 1 THEN
|
|
|
+
|
|
|
+ ELSIF a = -1 THEN
|
|
|
+ Neg(reg1)
|
|
|
+ ELSIF a = 0 THEN
|
|
|
+ Clear(reg1)
|
|
|
ELSE
|
|
|
- PushAll(1);
|
|
|
- PushImm(a);
|
|
|
- CallRTL(RTL._mul, 2);
|
|
|
- GetRegA
|
|
|
+ IF n > 0 THEN
|
|
|
+ IF a < 0 THEN
|
|
|
+ Neg(reg1)
|
|
|
+ END;
|
|
|
+ Shift2(IL.opLSL2, reg1, n)
|
|
|
+ ELSE
|
|
|
+ PushAll(1);
|
|
|
+ PushImm(a);
|
|
|
+ CallRTL(RTL._mul, 2);
|
|
|
+ GetRegA
|
|
|
+ END
|
|
|
END
|
|
|
- END
|
|
|
|
|
|
- |IL.opDIV:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(RTL._divmod, 2);
|
|
|
- GetRegA
|
|
|
+ |IL.opDIV:
|
|
|
+ PushAll(2);
|
|
|
+ CallRTL(RTL._divmod, 2);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opDIVR:
|
|
|
+ ASSERT(param2 > 0);
|
|
|
+
|
|
|
+ IF param2 > 1 THEN
|
|
|
+ n := UTILS.Log2(param2);
|
|
|
+ IF n > 0 THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ Shift2(IL.opASR2, reg1, n)
|
|
|
+ ELSE
|
|
|
+ PushAll(1);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._divmod, 2);
|
|
|
+ GetRegA
|
|
|
+ END
|
|
|
+ END
|
|
|
|
|
|
- |IL.opDIVR:
|
|
|
- ASSERT(param2 > 0);
|
|
|
+ |IL.opDIVL:
|
|
|
+ UnOp(reg1);
|
|
|
+ PushAll_1;
|
|
|
+ PushImm(param2);
|
|
|
+ Push(reg1);
|
|
|
+ drop;
|
|
|
+ CallRTL(RTL._divmod, 2);
|
|
|
+ GetRegA
|
|
|
|
|
|
- IF param2 > 1 THEN
|
|
|
- n := UTILS.Log2(param2);
|
|
|
- IF n > 0 THEN
|
|
|
+ |IL.opMOD:
|
|
|
+ PushAll(2);
|
|
|
+ CallRTL(RTL._divmod, 2);
|
|
|
+ ASSERT(REG.GetReg(R, R5))
|
|
|
+
|
|
|
+ |IL.opMODR:
|
|
|
+ ASSERT(param2 > 0);
|
|
|
+
|
|
|
+ IF param2 = 1 THEN
|
|
|
UnOp(reg1);
|
|
|
- Shift2(IL.opASR2, reg1, n)
|
|
|
+ Clear(reg1)
|
|
|
ELSE
|
|
|
- PushAll(1);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._divmod, 2);
|
|
|
- GetRegA
|
|
|
+ IF UTILS.Log2(param2) > 0 THEN
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opAND, imm(param2 - 1), reg1)
|
|
|
+ ELSE
|
|
|
+ PushAll(1);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._divmod, 2);
|
|
|
+ ASSERT(REG.GetReg(R, R5))
|
|
|
+ END
|
|
|
END
|
|
|
- END
|
|
|
|
|
|
- |IL.opDIVL:
|
|
|
- UnOp(reg1);
|
|
|
- PushAll_1;
|
|
|
- PushImm(param2);
|
|
|
- Push(reg1);
|
|
|
- drop;
|
|
|
- CallRTL(RTL._divmod, 2);
|
|
|
- GetRegA
|
|
|
+ |IL.opMODL:
|
|
|
+ UnOp(reg1);
|
|
|
+ PushAll_1;
|
|
|
+ PushImm(param2);
|
|
|
+ Push(reg1);
|
|
|
+ drop;
|
|
|
+ CallRTL(RTL._divmod, 2);
|
|
|
+ ASSERT(REG.GetReg(R, R5))
|
|
|
+
|
|
|
+ |IL.opCOPYS:
|
|
|
+ ASSERT(R.top = 3);
|
|
|
+ Push(R.stk[2]);
|
|
|
+ Push(R.stk[0]);
|
|
|
+ Op2(opCMP, R.stk[1] * 256, R.stk[3]);
|
|
|
+ EmitWord(3801H); (* JL L1 *)
|
|
|
+ MovRR(R.stk[1], R.stk[3]);
|
|
|
+ (* L1: *)
|
|
|
+ Push(R.stk[3]);
|
|
|
+ drop;
|
|
|
+ drop;
|
|
|
+ drop;
|
|
|
+ drop;
|
|
|
+ CallRTL(RTL._move, 3)
|
|
|
+
|
|
|
+ |IL.opCOPY:
|
|
|
+ PushAll(2);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._move, 3)
|
|
|
+
|
|
|
+ |IL.opMOVE:
|
|
|
+ PushAll(3);
|
|
|
+ CallRTL(RTL._move, 3)
|
|
|
+
|
|
|
+ |IL.opCOPYA:
|
|
|
+ PushAll(4);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._arrcpy, 5);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opROT:
|
|
|
+ PushAll(0);
|
|
|
+ MovRR(SP, ACC);
|
|
|
+ Push(ACC);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._rot, 2)
|
|
|
+
|
|
|
+ |IL.opSAVES:
|
|
|
+ UnOp(reg1);
|
|
|
+ PushAll_1;
|
|
|
+ Op1(opPUSH, PC, sINCR);
|
|
|
+ IncStk;
|
|
|
+ EmitWord(param2);
|
|
|
+ Reloc(RDATA);
|
|
|
+ Push(reg1);
|
|
|
+ drop;
|
|
|
+ PushImm(param1);
|
|
|
+ CallRTL(RTL._move, 3)
|
|
|
+
|
|
|
+ |IL.opCASET:
|
|
|
+ Push(R5);
|
|
|
+ Push(R5);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._guardrec, 2);
|
|
|
+ Pop(R5);
|
|
|
+ Test(ACC);
|
|
|
+ jcc(jne, param1)
|
|
|
+
|
|
|
+ |IL.opABS:
|
|
|
+ UnOp(reg1);
|
|
|
+ Test(reg1);
|
|
|
+ L := NewLabel();
|
|
|
+ jcc(jge, L);
|
|
|
+ Neg(reg1);
|
|
|
+ EmitLabel(L)
|
|
|
|
|
|
- |IL.opMOD:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(RTL._divmod, 2);
|
|
|
- ASSERT(REG.GetReg(R, R5))
|
|
|
+ |IL.opEQB, IL.opNEB:
|
|
|
+ BinOp(reg1, reg2);
|
|
|
+ drop;
|
|
|
|
|
|
- |IL.opMODR:
|
|
|
- ASSERT(param2 > 0);
|
|
|
+ Test(reg1);
|
|
|
+ L := NewLabel();
|
|
|
+ jcc(je, L);
|
|
|
+ Op2(opMOV, imm(1), reg1);
|
|
|
+ EmitLabel(L);
|
|
|
|
|
|
- IF param2 = 1 THEN
|
|
|
- UnOp(reg1);
|
|
|
- Clear(reg1)
|
|
|
- ELSE
|
|
|
- IF UTILS.Log2(param2) > 0 THEN
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opAND, imm(param2 - 1), reg1)
|
|
|
+ Test(reg2);
|
|
|
+ L := NewLabel();
|
|
|
+ jcc(je, L);
|
|
|
+ Op2(opMOV, imm(1), reg2);
|
|
|
+ EmitLabel(L);
|
|
|
+
|
|
|
+ Op2(opCMP, reg2 * 256, reg1);
|
|
|
+ IF opcode = IL.opEQB THEN
|
|
|
+ setcc(je, reg1)
|
|
|
ELSE
|
|
|
- PushAll(1);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._divmod, 2);
|
|
|
- ASSERT(REG.GetReg(R, R5))
|
|
|
+ setcc(jne, reg1)
|
|
|
END
|
|
|
- END
|
|
|
|
|
|
- |IL.opMODL:
|
|
|
- UnOp(reg1);
|
|
|
- PushAll_1;
|
|
|
- PushImm(param2);
|
|
|
- Push(reg1);
|
|
|
- drop;
|
|
|
- CallRTL(RTL._divmod, 2);
|
|
|
- ASSERT(REG.GetReg(R, R5))
|
|
|
-
|
|
|
- |IL.opCOPYS:
|
|
|
- ASSERT(R.top = 3);
|
|
|
- Push(R.stk[2]);
|
|
|
- Push(R.stk[0]);
|
|
|
- Op2(opCMP, R.stk[1] * 256, R.stk[3]);
|
|
|
- EmitWord(3801H); (* JL L1 *)
|
|
|
- MovRR(R.stk[1], R.stk[3]);
|
|
|
- (* L1: *)
|
|
|
- Push(R.stk[3]);
|
|
|
- drop;
|
|
|
- drop;
|
|
|
- drop;
|
|
|
- drop;
|
|
|
- CallRTL(RTL._move, 3)
|
|
|
-
|
|
|
- |IL.opCOPY:
|
|
|
- PushAll(2);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._move, 3)
|
|
|
-
|
|
|
- |IL.opMOVE:
|
|
|
- PushAll(3);
|
|
|
- CallRTL(RTL._move, 3)
|
|
|
-
|
|
|
- |IL.opCOPYA:
|
|
|
- PushAll(4);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._arrcpy, 5);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opROT:
|
|
|
- PushAll(0);
|
|
|
- MovRR(SP, ACC);
|
|
|
- Push(ACC);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._rot, 2)
|
|
|
-
|
|
|
- |IL.opSAVES:
|
|
|
- UnOp(reg1);
|
|
|
- PushAll_1;
|
|
|
- Op1(opPUSH, PC, sINCR);
|
|
|
- IncStk;
|
|
|
- EmitWord(param2);
|
|
|
- Reloc(RDATA);
|
|
|
- Push(reg1);
|
|
|
- drop;
|
|
|
- PushImm(param1);
|
|
|
- CallRTL(RTL._move, 3)
|
|
|
-
|
|
|
- |IL.opCASET:
|
|
|
- Push(R5);
|
|
|
- Push(R5);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._guardrec, 2);
|
|
|
- Pop(R5);
|
|
|
- Test(ACC);
|
|
|
- jcc(jne, param1)
|
|
|
-
|
|
|
- |IL.opABS:
|
|
|
- UnOp(reg1);
|
|
|
- Test(reg1);
|
|
|
- L := NewLabel();
|
|
|
- jcc(jge, L);
|
|
|
- Neg(reg1);
|
|
|
- EmitLabel(L)
|
|
|
+ |IL.opSAVEP:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opMOV, incr(PC), reg1 + dIDX);
|
|
|
+ EmitWord(param2);
|
|
|
+ Reloc(RCODE);
|
|
|
+ EmitWord(0);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opEQB, IL.opNEB:
|
|
|
- BinOp(reg1, reg2);
|
|
|
- drop;
|
|
|
+ |IL.opPUSHP:
|
|
|
+ Op2(opMOV, incr(PC), GetAnyReg());
|
|
|
+ EmitWord(param2);
|
|
|
+ Reloc(RCODE)
|
|
|
|
|
|
- Test(reg1);
|
|
|
- L := NewLabel();
|
|
|
- jcc(je, L);
|
|
|
- Op2(opMOV, imm(1), reg1);
|
|
|
- EmitLabel(L);
|
|
|
+ |IL.opEQP, IL.opNEP:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opCMP, incr(PC), reg1);
|
|
|
+ EmitWord(param1);
|
|
|
+ Reloc(RCODE);
|
|
|
+ drop;
|
|
|
+ reg1 := GetAnyReg();
|
|
|
|
|
|
- Test(reg2);
|
|
|
- L := NewLabel();
|
|
|
- jcc(je, L);
|
|
|
- Op2(opMOV, imm(1), reg2);
|
|
|
- EmitLabel(L);
|
|
|
+ IF opcode = IL.opEQP THEN
|
|
|
+ setcc(je, reg1)
|
|
|
+ ELSIF opcode = IL.opNEP THEN
|
|
|
+ setcc(jne, reg1)
|
|
|
+ END
|
|
|
|
|
|
- Op2(opCMP, reg2 * 256, reg1);
|
|
|
- IF opcode = IL.opEQB THEN
|
|
|
- setcc(je, reg1)
|
|
|
- ELSE
|
|
|
- setcc(jne, reg1)
|
|
|
- END
|
|
|
+ |IL.opVADR_PARAM:
|
|
|
+ reg1 := GetAnyReg();
|
|
|
+ Op2(opMOV, LocalSrc(param2), reg1);
|
|
|
+ Push(reg1);
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opSAVEP:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opMOV, incr(PC), reg1 + dIDX);
|
|
|
- EmitWord(param2);
|
|
|
- Reloc(RCODE);
|
|
|
- EmitWord(0);
|
|
|
- drop
|
|
|
+ |IL.opNEW:
|
|
|
+ PushAll(1);
|
|
|
+ n := param2 + 2;
|
|
|
+ ASSERT(UTILS.Align(n, 2));
|
|
|
+ PushImm(n);
|
|
|
+ PushImm(param1);
|
|
|
+ CallRTL(RTL._new, 3)
|
|
|
|
|
|
- |IL.opPUSHP:
|
|
|
- Op2(opMOV, incr(PC), GetAnyReg());
|
|
|
- EmitWord(param2);
|
|
|
- Reloc(RCODE)
|
|
|
+ |IL.opRSET:
|
|
|
+ PushAll(2);
|
|
|
+ CallRTL(RTL._set, 2);
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opEQP, IL.opNEP:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opCMP, incr(PC), reg1);
|
|
|
- EmitWord(param1);
|
|
|
- Reloc(RCODE);
|
|
|
- drop;
|
|
|
- reg1 := GetAnyReg();
|
|
|
+ |IL.opRSETR:
|
|
|
+ PushAll(1);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._set, 2);
|
|
|
+ GetRegA
|
|
|
|
|
|
- IF opcode = IL.opEQP THEN
|
|
|
- setcc(je, reg1)
|
|
|
- ELSIF opcode = IL.opNEP THEN
|
|
|
- setcc(jne, reg1)
|
|
|
- END
|
|
|
+ |IL.opRSETL:
|
|
|
+ UnOp(reg1);
|
|
|
+ PushAll_1;
|
|
|
+ PushImm(param2);
|
|
|
+ Push(reg1);
|
|
|
+ drop;
|
|
|
+ CallRTL(RTL._set, 2);
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opVADR_PARAM:
|
|
|
- reg1 := GetAnyReg();
|
|
|
- Op2(opMOV, LocalSrc(param2), reg1);
|
|
|
- Push(reg1);
|
|
|
- drop
|
|
|
+ |IL.opRSET1:
|
|
|
+ PushAll(1);
|
|
|
+ CallRTL(RTL._set1, 1);
|
|
|
+ GetRegA
|
|
|
|
|
|
- |IL.opNEW:
|
|
|
- PushAll(1);
|
|
|
- n := param2 + 2;
|
|
|
- ASSERT(UTILS.Align(n, 2));
|
|
|
- PushImm(n);
|
|
|
- PushImm(param1);
|
|
|
- CallRTL(RTL._new, 3)
|
|
|
-
|
|
|
- |IL.opRSET:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(RTL._set, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opRSETR:
|
|
|
- PushAll(1);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._set, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opRSETL:
|
|
|
- UnOp(reg1);
|
|
|
- PushAll_1;
|
|
|
- PushImm(param2);
|
|
|
- Push(reg1);
|
|
|
- drop;
|
|
|
- CallRTL(RTL._set, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opRSET1:
|
|
|
- PushAll(1);
|
|
|
- CallRTL(RTL._set1, 1);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opINCLC:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opBIS, imm(ORD({param2})), dst_x(0, reg1));
|
|
|
- drop
|
|
|
+ |IL.opINCLC:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opBIS, imm(ORD({param2})), dst_x(0, reg1));
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opEXCLC:
|
|
|
- UnOp(reg1);
|
|
|
- Op2(opBIC, imm(ORD({param2})), dst_x(0, reg1));
|
|
|
- drop
|
|
|
+ |IL.opEXCLC:
|
|
|
+ UnOp(reg1);
|
|
|
+ Op2(opBIC, imm(ORD({param2})), dst_x(0, reg1));
|
|
|
+ drop
|
|
|
|
|
|
- |IL.opIN:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(RTL._in, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opINR:
|
|
|
- PushAll(1);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._in, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opINL:
|
|
|
- PushAll(1);
|
|
|
- PushImm(param2);
|
|
|
- CallRTL(RTL._in2, 2);
|
|
|
- GetRegA
|
|
|
-
|
|
|
- |IL.opINCL:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(RTL._incl, 2)
|
|
|
-
|
|
|
- |IL.opEXCL:
|
|
|
- PushAll(2);
|
|
|
- CallRTL(RTL._excl, 2)
|
|
|
-
|
|
|
- |IL.opLADR_INCL, IL.opLADR_EXCL:
|
|
|
- PushAll(1);
|
|
|
- MovRR(SP, ACC);
|
|
|
- n := LocalOffset(param2);
|
|
|
- IF n # 0 THEN
|
|
|
- Op2(opADD, imm(n), ACC)
|
|
|
- END;
|
|
|
- Push(ACC);
|
|
|
- IF opcode = IL.opLADR_INCL THEN
|
|
|
+ |IL.opIN:
|
|
|
+ PushAll(2);
|
|
|
+ CallRTL(RTL._in, 2);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opINR:
|
|
|
+ PushAll(1);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._in, 2);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opINL:
|
|
|
+ PushAll(1);
|
|
|
+ PushImm(param2);
|
|
|
+ CallRTL(RTL._in2, 2);
|
|
|
+ GetRegA
|
|
|
+
|
|
|
+ |IL.opINCL:
|
|
|
+ PushAll(2);
|
|
|
CallRTL(RTL._incl, 2)
|
|
|
- ELSIF opcode = IL.opLADR_EXCL THEN
|
|
|
+
|
|
|
+ |IL.opEXCL:
|
|
|
+ PushAll(2);
|
|
|
CallRTL(RTL._excl, 2)
|
|
|
- END
|
|
|
|
|
|
- |IL.opLADR_INCLC:
|
|
|
- Op2(opBIS, imm(ORD({param2})), LocalDst(param1))
|
|
|
+ |IL.opLADR_INCL, IL.opLADR_EXCL:
|
|
|
+ PushAll(1);
|
|
|
+ MovRR(SP, ACC);
|
|
|
+ n := LocalOffset(param2);
|
|
|
+ IF n # 0 THEN
|
|
|
+ Op2(opADD, imm(n), ACC)
|
|
|
+ END;
|
|
|
+ Push(ACC);
|
|
|
+ IF opcode = IL.opLADR_INCL THEN
|
|
|
+ CallRTL(RTL._incl, 2)
|
|
|
+ ELSIF opcode = IL.opLADR_EXCL THEN
|
|
|
+ CallRTL(RTL._excl, 2)
|
|
|
+ END
|
|
|
|
|
|
- |IL.opLADR_EXCLC:
|
|
|
- Op2(opBIC, imm(ORD({param2})), LocalDst(param1))
|
|
|
+ |IL.opLADR_INCLC:
|
|
|
+ Op2(opBIS, imm(ORD({param2})), LocalDst(param1))
|
|
|
|
|
|
- END;
|
|
|
+ |IL.opLADR_EXCLC:
|
|
|
+ Op2(opBIC, imm(ORD({param2})), LocalDst(param1))
|
|
|
|
|
|
- cmd := cmd.next(COMMAND)
|
|
|
- END;
|
|
|
+ END;
|
|
|
+
|
|
|
+ cmd := cmd.next(COMMAND)
|
|
|
+ END;
|
|
|
|
|
|
- ASSERT(R.pushed = 0);
|
|
|
- ASSERT(R.top = -1)
|
|
|
-END translate;
|
|
|
+ ASSERT(R.pushed = 0);
|
|
|
+ ASSERT(R.top = -1)
|
|
|
+ END translate;
|
|
|
|
|
|
|
|
|
PROCEDURE prolog;
|
|
|
-VAR
|
|
|
- i: INTEGER;
|
|
|
+ VAR
|
|
|
+ i: INTEGER;
|
|
|
|
|
|
-BEGIN
|
|
|
- RTL.Init(EmitLabel, EmitWord, EmitCall);
|
|
|
- FOR i := 0 TO LEN(RTL.rtl) - 1 DO
|
|
|
- RTL.Set(i, NewLabel())
|
|
|
- END;
|
|
|
+ BEGIN
|
|
|
+ RTL.Init(EmitLabel, EmitWord, EmitCall);
|
|
|
+ FOR i := 0 TO LEN(RTL.rtl) - 1 DO
|
|
|
+ RTL.Set(i, NewLabel())
|
|
|
+ END;
|
|
|
|
|
|
- IV[LEN(IV) - 1] := NewLabel();
|
|
|
- EmitLabel(IV[LEN(IV) - 1]);
|
|
|
- Op2(opMOV, incr(PC), SP);
|
|
|
- EmitWord(0);
|
|
|
- Op2(opMOV, incr(PC), HP);
|
|
|
- EmitWord(0);
|
|
|
- Op2(opMOV, imm(5A80H), dst_x(0120H, SR)); (* stop WDT *)
|
|
|
- Op2(opMOV, imm(RTL.empty_proc), dst_x(0, SP));
|
|
|
- Op2(opMOV, imm(RTL.empty_proc), dst_x(2, SP));
|
|
|
-END prolog;
|
|
|
+ IV[LEN(IV) - 1] := NewLabel();
|
|
|
+ EmitLabel(IV[LEN(IV) - 1]);
|
|
|
+ Op2(opMOV, incr(PC), SP);
|
|
|
+ EmitWord(0);
|
|
|
+ Op2(opMOV, incr(PC), HP);
|
|
|
+ EmitWord(0);
|
|
|
+ Op2(opMOV, imm(5A80H), dst_x(0120H, SR)); (* stop WDT *)
|
|
|
+ Op2(opMOV, imm(RTL.empty_proc), dst_x(0, SP));
|
|
|
+ Op2(opMOV, imm(RTL.empty_proc), dst_x(2, SP));
|
|
|
+ END prolog;
|
|
|
|
|
|
|
|
|
PROCEDURE epilog;
|
|
|
-VAR
|
|
|
- L1, i, n: INTEGER;
|
|
|
-
|
|
|
-BEGIN
|
|
|
- Op2(opBIS, imm(10H), SR); (* CPUOFF *)
|
|
|
-
|
|
|
- L1 := NewLabel();
|
|
|
- FOR i := 0 TO LEN(IV) - 2 DO
|
|
|
- IV[i] := NewLabel();
|
|
|
- EmitLabel(IV[i]);
|
|
|
- PushImm(i);
|
|
|
- IF i # LEN(IV) - 2 THEN
|
|
|
- EmitJmp(opJMP, L1)
|
|
|
- END
|
|
|
- END;
|
|
|
+ VAR
|
|
|
+ L1, i, n: INTEGER;
|
|
|
+
|
|
|
+ BEGIN
|
|
|
+ Op2(opBIS, imm(10H), SR); (* CPUOFF *)
|
|
|
+
|
|
|
+ L1 := NewLabel();
|
|
|
+ FOR i := 0 TO LEN(IV) - 2 DO
|
|
|
+ IV[i] := NewLabel();
|
|
|
+ EmitLabel(IV[i]);
|
|
|
+ PushImm(i);
|
|
|
+ IF i # LEN(IV) - 2 THEN
|
|
|
+ EmitJmp(opJMP, L1)
|
|
|
+ END
|
|
|
+ END;
|
|
|
|
|
|
- EmitLabel(L1);
|
|
|
+ EmitLabel(L1);
|
|
|
|
|
|
- n := 0;
|
|
|
- FOR i := 0 TO 15 DO
|
|
|
- IF i IN R.regs THEN
|
|
|
- Push(i);
|
|
|
- INC(n)
|
|
|
- END
|
|
|
- END;
|
|
|
+ n := 0;
|
|
|
+ FOR i := 0 TO 15 DO
|
|
|
+ IF i IN R.regs THEN
|
|
|
+ Push(i);
|
|
|
+ INC(n)
|
|
|
+ END
|
|
|
+ END;
|
|
|
|
|
|
- MovRR(SP, R4);
|
|
|
- Op2(opADD, imm(n * 2), R4);
|
|
|
+ MovRR(SP, R4);
|
|
|
+ Op2(opADD, imm(n * 2), R4);
|
|
|
|
|
|
- Push(R4);
|
|
|
- Op1(opPUSH, R4, sINDIR);
|
|
|
- Op1(opCALL, SR, sIDX); EmitWord(-RTL.VarSize); Reloc(RBSS); (* call int *)
|
|
|
- Op2(opADD, imm(4), SP);
|
|
|
+ Push(R4);
|
|
|
+ Op1(opPUSH, R4, sINDIR);
|
|
|
+ Op1(opCALL, SR, sIDX); EmitWord(-RTL.VarSize); Reloc(RBSS); (* call int *)
|
|
|
+ Op2(opADD, imm(4), SP);
|
|
|
|
|
|
- FOR i := 15 TO 0 BY -1 DO
|
|
|
- IF i IN R.regs THEN
|
|
|
- Pop(i)
|
|
|
- END
|
|
|
- END;
|
|
|
+ FOR i := 15 TO 0 BY -1 DO
|
|
|
+ IF i IN R.regs THEN
|
|
|
+ Pop(i)
|
|
|
+ END
|
|
|
+ END;
|
|
|
|
|
|
- Op2(opADD, imm(2), SP);
|
|
|
- Op1(opRETI, 0, 0);
|
|
|
+ Op2(opADD, imm(2), SP);
|
|
|
+ Op1(opRETI, 0, 0);
|
|
|
|
|
|
- RTL.Gen
|
|
|
-END epilog;
|
|
|
+ RTL.Gen
|
|
|
+ END epilog;
|
|
|
|
|
|
|
|
|
PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS);
|
|
|
-VAR
|
|
|
- i, adr, heap, stack, TextSize, TypesSize, bits, n, val: INTEGER;
|
|
|
+ VAR
|
|
|
+ i, adr, heap, stack, TextSize, TypesSize, bits, n, val: INTEGER;
|
|
|
|
|
|
- Code, Data, Bss: RECORD address, size: INTEGER END;
|
|
|
+ Code, Data, Bss: RECORD address, size: INTEGER END;
|
|
|
|
|
|
- ram, rom: INTEGER;
|
|
|
+ ram, rom: INTEGER;
|
|
|
|
|
|
- reloc: RELOC;
|
|
|
+ reloc: RELOC;
|
|
|
|
|
|
-BEGIN
|
|
|
- IdxWords.src := NOWORD;
|
|
|
- IdxWords.dst := NOWORD;
|
|
|
+ BEGIN
|
|
|
+ IdxWords.src := NOWORD;
|
|
|
+ IdxWords.dst := NOWORD;
|
|
|
|
|
|
- ram := options.ram;
|
|
|
- rom := options.rom;
|
|
|
+ ram := options.ram;
|
|
|
+ rom := options.rom;
|
|
|
|
|
|
- IF ODD(ram) THEN DEC(ram) END;
|
|
|
- IF ODD(rom) THEN DEC(rom) END;
|
|
|
+ IF ODD(ram) THEN DEC(ram) END;
|
|
|
+ IF ODD(rom) THEN DEC(rom) END;
|
|
|
|
|
|
- ram := MIN(MAX(ram, minRAM), maxRAM);
|
|
|
- rom := MIN(MAX(rom, minROM), maxROM);
|
|
|
+ ram := MIN(MAX(ram, minRAM), maxRAM);
|
|
|
+ rom := MIN(MAX(rom, minROM), maxROM);
|
|
|
|
|
|
- IF IL.codes.bss > ram - StkReserve - RTL.VarSize THEN
|
|
|
- ERRORS.Error(204)
|
|
|
- END;
|
|
|
+ IF IL.codes.bss > ram - StkReserve - RTL.VarSize THEN
|
|
|
+ ERRORS.Error(204)
|
|
|
+ END;
|
|
|
|
|
|
- Labels := CHL.CreateIntList();
|
|
|
- FOR i := 1 TO IL.codes.lcount DO
|
|
|
- CHL.PushInt(Labels, 0)
|
|
|
- END;
|
|
|
+ Labels := CHL.CreateIntList();
|
|
|
+ FOR i := 1 TO IL.codes.lcount DO
|
|
|
+ CHL.PushInt(Labels, 0)
|
|
|
+ END;
|
|
|
|
|
|
- CodeList := LISTS.create(NIL);
|
|
|
- RelList := LISTS.create(NIL);
|
|
|
- REG.Init(R, Push, Pop, mov, xchg, {R4, R5, R6, R7});
|
|
|
+ CodeList := LISTS.create(NIL);
|
|
|
+ RelList := LISTS.create(NIL);
|
|
|
+ REG.Init(R, Push, Pop, mov, xchg, {R4, R5, R6, R7});
|
|
|
|
|
|
- prolog;
|
|
|
- translate(chkSTK IN options.checking);
|
|
|
- epilog;
|
|
|
+ prolog;
|
|
|
+ translate(chkSTK IN options.checking);
|
|
|
+ epilog;
|
|
|
|
|
|
- TypesSize := CHL.Length(IL.codes.types) * 2;
|
|
|
- Data.size := CHL.Length(IL.codes.data);
|
|
|
- IF ODD(Data.size) THEN
|
|
|
- CHL.PushByte(IL.codes.data, 0);
|
|
|
- INC(Data.size)
|
|
|
- END;
|
|
|
- Code.size := Fixup(0, IntVectorSize + TypesSize + Data.size);
|
|
|
- Code.address := 10000H - (IntVectorSize + TypesSize + Data.size + Code.size);
|
|
|
- IF Code.address < 10000H - rom THEN
|
|
|
- ERRORS.Error(203)
|
|
|
- END;
|
|
|
- Code.size := Fixup(Code.address, IntVectorSize + TypesSize + Data.size);
|
|
|
- Data.address := Code.address + Code.size;
|
|
|
- TextSize := Code.size + Data.size;
|
|
|
+ TypesSize := CHL.Length(IL.codes.types) * 2;
|
|
|
+ Data.size := CHL.Length(IL.codes.data);
|
|
|
+ IF ODD(Data.size) THEN
|
|
|
+ CHL.PushByte(IL.codes.data, 0);
|
|
|
+ INC(Data.size)
|
|
|
+ END;
|
|
|
+ Code.size := Fixup(0, IntVectorSize + TypesSize + Data.size);
|
|
|
+ Code.address := 10000H - (IntVectorSize + TypesSize + Data.size + Code.size);
|
|
|
+ IF Code.address < 10000H - rom THEN
|
|
|
+ ERRORS.Error(203)
|
|
|
+ END;
|
|
|
+ Code.size := Fixup(Code.address, IntVectorSize + TypesSize + Data.size);
|
|
|
+ Data.address := Code.address + Code.size;
|
|
|
+ TextSize := Code.size + Data.size;
|
|
|
|
|
|
- IF Code.address + TextSize + MAX(IL.codes.dmin - Data.size, IntVectorSize + TypesSize) > 10000H THEN
|
|
|
- ERRORS.Error(203)
|
|
|
- END;
|
|
|
+ IF Code.address + TextSize + MAX(IL.codes.dmin - Data.size, IntVectorSize + TypesSize) > 10000H THEN
|
|
|
+ ERRORS.Error(203)
|
|
|
+ END;
|
|
|
|
|
|
- stack := RTL.ram + ram;
|
|
|
- Bss.size := IL.codes.bss + IL.codes.bss MOD 2;
|
|
|
- DEC(stack, Bss.size);
|
|
|
- Bss.address := stack;
|
|
|
- DEC(stack, RTL.VarSize);
|
|
|
- heap := RTL.ram;
|
|
|
- ASSERT(stack - heap >= StkReserve);
|
|
|
- adr := Code.address + 2;
|
|
|
- PutWord(stack, adr);
|
|
|
- adr := Code.address + 6;
|
|
|
- PutWord(heap, adr);
|
|
|
-
|
|
|
- reloc := RelList.first(RELOC);
|
|
|
- WHILE reloc # NIL DO
|
|
|
- adr := reloc.WordPtr.offset * 2;
|
|
|
- val := reloc.WordPtr.val;
|
|
|
- CASE reloc.section OF
|
|
|
- |RCODE: PutWord(LabelOffs(val) * 2, adr)
|
|
|
- |RDATA: PutWord(val + Data.address, adr)
|
|
|
- |RBSS: PutWord((val + Bss.address) MOD 65536, adr)
|
|
|
+ stack := RTL.ram + ram;
|
|
|
+ Bss.size := IL.codes.bss + IL.codes.bss MOD 2;
|
|
|
+ DEC(stack, Bss.size);
|
|
|
+ Bss.address := stack;
|
|
|
+ DEC(stack, RTL.VarSize);
|
|
|
+ heap := RTL.ram;
|
|
|
+ ASSERT(stack - heap >= StkReserve);
|
|
|
+ adr := Code.address + 2;
|
|
|
+ PutWord(stack, adr);
|
|
|
+ adr := Code.address + 6;
|
|
|
+ PutWord(heap, adr);
|
|
|
+
|
|
|
+ reloc := RelList.first(RELOC);
|
|
|
+ WHILE reloc # NIL DO
|
|
|
+ adr := reloc.WordPtr.offset * 2;
|
|
|
+ val := reloc.WordPtr.val;
|
|
|
+ CASE reloc.section OF
|
|
|
+ |RCODE: PutWord(LabelOffs(val) * 2, adr)
|
|
|
+ |RDATA: PutWord(val + Data.address, adr)
|
|
|
+ |RBSS: PutWord((val + Bss.address) MOD 65536, adr)
|
|
|
+ END;
|
|
|
+ reloc := reloc.next(RELOC)
|
|
|
END;
|
|
|
- reloc := reloc.next(RELOC)
|
|
|
- END;
|
|
|
|
|
|
- adr := Data.address;
|
|
|
+ adr := Data.address;
|
|
|
|
|
|
- FOR i := 0 TO Data.size - 1 DO
|
|
|
- mem[adr] := CHL.GetByte(IL.codes.data, i);
|
|
|
- INC(adr)
|
|
|
- END;
|
|
|
+ FOR i := 0 TO Data.size - 1 DO
|
|
|
+ mem[adr] := CHL.GetByte(IL.codes.data, i);
|
|
|
+ INC(adr)
|
|
|
+ END;
|
|
|
|
|
|
- FOR i := TypesSize DIV 2 - 1 TO 0 BY -1 DO
|
|
|
- PutWord(CHL.GetInt(IL.codes.types, i), adr)
|
|
|
- END;
|
|
|
+ FOR i := TypesSize DIV 2 - 1 TO 0 BY -1 DO
|
|
|
+ PutWord(CHL.GetInt(IL.codes.types, i), adr)
|
|
|
+ END;
|
|
|
|
|
|
- FOR i := 0 TO 15 DO
|
|
|
- PutWord((33 - i) * i, adr);
|
|
|
- END;
|
|
|
+ FOR i := 0 TO 15 DO
|
|
|
+ PutWord((33 - i) * i, adr);
|
|
|
+ END;
|
|
|
|
|
|
- FOR n := 0 TO 15 DO
|
|
|
- bits := ORD({0 .. n});
|
|
|
- FOR i := 0 TO 15 - n DO
|
|
|
- PutWord(bits, adr);
|
|
|
- bits := LSL(bits, 1)
|
|
|
- END
|
|
|
- END;
|
|
|
+ FOR n := 0 TO 15 DO
|
|
|
+ bits := ORD({0 .. n});
|
|
|
+ FOR i := 0 TO 15 - n DO
|
|
|
+ PutWord(bits, adr);
|
|
|
+ bits := LSL(bits, 1)
|
|
|
+ END
|
|
|
+ END;
|
|
|
|
|
|
- PutWord(4130H, adr); (* RET *)
|
|
|
- PutWord(stack, adr);
|
|
|
- PutWord(0001H, adr); (* bsl signature (adr 0FFBEH) *)
|
|
|
+ PutWord(4130H, adr); (* RET *)
|
|
|
+ PutWord(stack, adr);
|
|
|
+ PutWord(0001H, adr); (* bsl signature (adr 0FFBEH) *)
|
|
|
|
|
|
- FOR i := 0 TO LEN(IV) - 1 DO
|
|
|
- PutWord(LabelOffs(IV[i]) * 2, adr)
|
|
|
- END;
|
|
|
+ FOR i := 0 TO LEN(IV) - 1 DO
|
|
|
+ PutWord(LabelOffs(IV[i]) * 2, adr)
|
|
|
+ END;
|
|
|
|
|
|
- INC(TextSize, IntVectorSize + TypesSize + Code.address MOD 16);
|
|
|
- INC(Bss.size, StkReserve + RTL.VarSize);
|
|
|
+ INC(TextSize, IntVectorSize + TypesSize + Code.address MOD 16);
|
|
|
+ INC(Bss.size, StkReserve + RTL.VarSize);
|
|
|
|
|
|
- WR.Create(outname);
|
|
|
- HEX.Data(mem, Code.address - Code.address MOD 16, TextSize);
|
|
|
- HEX.End;
|
|
|
- WR.Close;
|
|
|
+ WR.Create(outname);
|
|
|
+ HEX.Data(mem, Code.address - Code.address MOD 16, TextSize);
|
|
|
+ HEX.End;
|
|
|
+ WR.Close;
|
|
|
|
|
|
- C.Dashes;
|
|
|
- C.String(" rom: "); C.Int(TextSize); C.String(" of "); C.Int(rom); C.String(" ("); C.Int(TextSize * 100 DIV rom); C.StringLn("%)");
|
|
|
- C.Ln;
|
|
|
- C.String(" ram: "); C.Int(Bss.size); C.String(" of "); C.Int(ram); C.String(" ("); C.Int(Bss.size * 100 DIV ram); C.StringLn("%)")
|
|
|
-END CodeGen;
|
|
|
+ C.Dashes;
|
|
|
+ C.String(" rom: "); C.Int(TextSize); C.String(" of "); C.Int(rom); C.String(" ("); C.Int(TextSize * 100 DIV rom); C.StringLn("%)");
|
|
|
+ C.Ln;
|
|
|
+ C.String(" ram: "); C.Int(Bss.size); C.String(" of "); C.Int(ram); C.String(" ("); C.Int(Bss.size * 100 DIV ram); C.StringLn("%)")
|
|
|
+ END CodeGen;
|
|
|
|
|
|
|
|
|
END MSP430.
|