220220 RegCacheLeavesValue(hireg(reg), sym, off);
221221 end sub;
222222
223- sub E_loadix(reg: RegId, ptr: RegId, off: Arith, byte: uint8 ) is
223+ sub E_loadix(reg: RegId, ptr: RegId, off: Arith) is
224224 R_flush(reg);
225225 E_mov(reg);
226226 if off != 0 then
261261 E_nl();
262262 end sub;
263263
264- sub E_storeix(reg: RegId, ptr: RegId, off: Arith, byte: uint8 ) is
264+ sub E_storeix(reg: RegId, ptr: RegId, off: Arith) is
265265 E_mov(reg);
266266 E_reg(reg);
267267 E(", ");
315315
316316#
317317
318- sub E_jump(insn: string, label: LabelRef) is
319- R_flushall();
318+ sub E_jump_noflush(insn: string, label: LabelRef) is
320319 E_tab();
321320 E(insn);
322321 E_tab();
323322 E_labelref(label);
324323 E_nl();
325324 end sub;
326325
326+ sub E_jump(insn: string, label: LabelRef) is
327+ R_flushall();
328+ E_jump_noflush(insn, label);
329+ end sub;
330+
327331 sub E_jmp(label: LabelRef) is
328332 E_jump("BR", label);
329333 end sub;
480484 E_alu2i_noflush(insn, value, dest);
481485 end sub;
482486
483- sub E_alu2wi(insn: string, value: Arith, dest: RegId) is
484- R_flush(dest);
485- E_insn16(insn);
486- E_b8('#');
487- if value < 0 then
488- E_b8('-');
489- value := -value;
490- end if;
491- E_u32(value as uint32);
492- E(", ");
493- E_reg(dest);
494- E_nl();
495- end sub;
496-
497487 sub E_addi(value: Arith, dest: RegId) is
498488 case value is
499489 when 1: E_inc(dest);
500490 when -1: E_dec(dest);
501- when else: E_alu2wi ("ADD", value, dest);
491+ when else: E_alu2i ("ADD", value, hireg( dest) );
502492 end case;
503493 end sub;
504494
505495 sub E_addi4(value: Arith, dest: RegId) is
506496 if (value & 0xffff) != 0 then
507- E_alu2wi ("ADD", value & 0xffff, loreg(dest));
497+ E_alu2i ("ADD", value & 0xffff, loreg(dest));
508498 E_adc(hireg(dest));
509499 end if;
510500 if (value >> 16) != 0 then
511- E_alu2wi ("ADD", value >> 16, hireg(dest));
501+ E_alu2i ("ADD", value >> 16, hireg(dest));
512502 end if;
513503 end sub;
514504
515505 sub E_subi(value: Arith, dest: RegId) is
516506 case value is
517507 when 1: E_dec(dest);
518508 when -1: E_inc(dest);
519- when else: E_alu2wi ("SUB", value, dest);
509+ when else: E_alu2i ("SUB", value, hireg( dest) );
520510 end case;
521511 end sub;
522512
523513 sub E_subi4(value: Arith, dest: RegId) is
524514 if (value & 0xffff) != 0 then
525- E_alu2wi ("SUB", value & 0xffff, loreg(dest));
515+ E_alu2i ("SUB", value & 0xffff, loreg(dest));
526516 E_sbc(hireg(dest));
527517 end if;
528518 if (value >> 16) != 0 then
529- E_alu2wi ("SUB", value >> 16, hireg(dest));
519+ E_alu2i ("SUB", value >> 16, hireg(dest));
530520 end if;
531521 end sub;
532522
556546 E_sub(hireg(rhs), hireg(lhs));
557547 end sub;
558548
549+ # can skip TST iff previous insn affected src and set flags
559550 sub E_cmpi(value: Arith, src: RegId) is
560- E_insn("CMP", src);
551+ if value == 0 then
552+ E_insn("TST", src);
553+ else
554+ E_insn("CMP", src);
555+ end if;
561556 E_reg(src);
562- E(", ");
563- E_b8('#');
564- E_i32(value);
557+ if value != 0 then
558+ E(", ");
559+ E_b8('#');
560+ E_i32(value);
561+ end if;
565562 E_nl();
566563 end sub;
567564
568565 sub E_cmpi4(value: Arith, reg: RegId) is
566+ var label := AllocPLabel();
569567 E_cmpi(value >> 16, hireg(reg));
570- E("\tbne\t$+6\n" );
568+ E_jump_noflush("bne", label );
571569 E_cmpi(value & 0xffff, loreg(reg));
570+ E_label(label);
572571 end sub;
573572
574573 sub E_sxtb(reg: RegId) is
906905 end if;
907906 end sub;
908907
908+ # sym is R8, dest is R16
909+ sub E_loadext(reg: RegId, sym: [Symbol], off: Size, sext: uint8) is
910+ R_flush(reg);
911+ if sext == 0 then
912+ E_clr(reg);
913+ E_insn("BIS", loreg(reg));
914+ else
915+ E_mov(loreg(reg));
916+ end if;
917+ E_symref(sym, off);
918+ E_comma();
919+ E_reg(reg);
920+ E_nl();
921+ end sub;
922+
909923 var stringid: uint16 := 0;
910924 sub E_string(data: string) is
911925 var sid := stringid;
@@ -1246,25 +1260,27 @@ gen r32 := CAST24(r16:val):c { E_move($val, loreg($$)); if ($c.sext != 0) then
12461260
12471261// --- Loads ---------------------------------------------------------------
12481262
1249- gen r8 := DEREF1(r16:rhs) { E_loadix($$, $rhs, 0, 1 ); }
1250- gen r16 := DEREF2(r16:rhs) { E_loadix($$, $rhs, 0, 0 ); }
1263+ gen r8 := DEREF1(r16:rhs) { E_loadix($$, $rhs, 0); }
1264+ gen r16 := DEREF2(r16:rhs) { E_loadix($$, $rhs, 0); }
12511265gen r32 := DEREF4(r16:rhs)
12521266{
12531267 if $rhs == loreg($$) then
1254- E_loadix(hireg($$), $rhs, 2, 0 ); E_loadix(loreg($$), $rhs, 0 , 0);
1268+ E_loadix(hireg($$), $rhs, 2); E_loadix(loreg($$), $rhs, 0);
12551269 else
1256- E_loadix(loreg($$), $rhs, 0, 0 ); E_loadix(hireg($$), $rhs, 2, 0 );
1270+ E_loadix(loreg($$), $rhs, 0); E_loadix(hireg($$), $rhs, 2);
12571271 end if;
12581272}
12591273
1260- gen r8 := DEREF1(ADD2(r16:rhs, CONSTANT():c)) { E_loadix($$, $rhs, $c.value, 1 ); }
1261- gen r16 := DEREF2(ADD2(r16:rhs, CONSTANT():c)) { E_loadix($$, $rhs, $c.value, 0 ); }
1274+ gen r8 := DEREF1(ADD2(r16:rhs, CONSTANT():c)) { E_loadix($$, $rhs, $c.value); }
1275+ gen r16 := DEREF2(ADD2(r16:rhs, CONSTANT():c)) { E_loadix($$, $rhs, $c.value); }
12621276gen r8 := DEREF1(ADD2(ADDRESS():a, CONSTANT():c)) { E_load($$, &$a.sym, $a.off + $c.value as uint16, 1); }
12631277gen r8 := DEREF1(ADD2(ADDRESS():a, r16:rhs)) { E_loadii($$, $rhs, &$a.sym, $a.off as uint16, 1); }
12641278gen r16 := DEREF2(ADD2(ADDRESS():a, CONSTANT():c)) { E_load($$, &$a.sym, $a.off + $c.value as uint16, 0); }
12651279gen r16 := DEREF2(ADD2(ADDRESS():a, r16:rhs)) { E_loadii($$, $rhs, &$a.sym, $a.off as uint16, 0); }
12661280
12671281gen r8 := DEREF1(ADDRESS():a) { E_load($$, &$a.sym, $a.off, 1); }
1282+ gen r16 := CAST12(DEREF1(ADDRESS():a)):c { E_loadext($$, &$a.sym, $a.off, $c.sext); }
1283+
12681284gen r16 := DEREF2(ADDRESS():a) { E_load($$, &$a.sym, $a.off, 0); }
12691285
12701286gen r32 := DEREF4(ADDRESS():a)
@@ -1275,11 +1291,11 @@ gen r32 := DEREF4(ADDRESS():a)
12751291gen r32 := DEREF4(ADD2(r16:rhs, CONSTANT():c))
12761292{
12771293 if $rhs == loreg($$) then
1278- E_loadix(hireg($$), $rhs, $c.value + 2, 0 );
1279- E_loadix(loreg($$), $rhs, $c.value, 0 );
1294+ E_loadix(hireg($$), $rhs, $c.value + 2);
1295+ E_loadix(loreg($$), $rhs, $c.value);
12801296 else
1281- E_loadix(loreg($$), $rhs, $c.value, 0 );
1282- E_loadix(hireg($$), $rhs, $c.value + 2, 0 );
1297+ E_loadix(loreg($$), $rhs, $c.value);
1298+ E_loadix(hireg($$), $rhs, $c.value + 2);
12831299 end if;
12841300}
12851301gen r32 := DEREF4(ADD2(ADDRESS():a, CONSTANT():c))
@@ -1294,31 +1310,30 @@ gen r16 := SUBREF():a { E_loadsubref($$, $a.subr); }
12941310
12951311// XXX otherwise regs get destroyed?
12961312//n r8 := CAST21(DEREF2(ADDRESS():a)):c { E_load($$, &$a.sym, $a.off, 0); }
1297- //n r16 := CAST12(DEREF1(r16:rhs)):c { E_loadix($$, $rhs, 0, 1); E_ext($$, $$, $c.sext); } // XXX bad code in FCBExt
1298- //n r16 := CAST12(DEREF1(ADDRESS():a)):c { E_load($$, &$a.sym, $a.off, 1); }
1313+ //n r16 := CAST12(DEREF1(r16:rhs)):c { E_loadix($$, $rhs, 0); E_ext($$, $$, $c.sext); } // XXX bad code in FCBExt
12991314//n r32 := CAST24(DEREF2(ADDRESS():a)):c { E_load(loreg($$), &$a.sym, $a.off, 0); if ($c.sext == 0) then E_clr(hireg($$)); else E_sxt(hireg($$)); end if; }
13001315//n r32 := CAST14(DEREF1(ADDRESS():a)):c { E_load(loreg($$), &$a.sym, $a.off, 1); E_ext(loreg($$), loreg($$), $c.sext); if ($c.sext != 0) then E_sxt(hireg($$)); else E_clr(hireg($$)); end if; }
13011316
13021317// --- Stores ---------------------------------------------------------------
13031318
13041319gen STORE1(CONSTANT():v, DEREF1(r16:rhs)) { E_storeixc($v.value, $rhs, 0, 1); }
13051320gen STORE1(CONSTANT():v, DEREF1(ADD2(r16:rhs, CONSTANT():c))) { E_storeixc($v.value, $rhs, $c.value, 1); }
1306- gen STORE1(r8:lhs, DEREF1(r16:rhs)) { E_storeix($lhs, $rhs, 0, 1 ); }
1321+ gen STORE1(r8:lhs, DEREF1(r16:rhs)) { E_storeix($lhs, $rhs, 0); }
13071322gen STORE1(r8:lhs, DEREF1(ADDRESS():a)) { E_store($lhs, &$a.sym, $a.off, 1); }
1308- gen STORE1(r8:lhs, DEREF1(ADD2(r16:rhs, CONSTANT():c))) { E_storeix($lhs, $rhs, $c.value, 1 ); }
1323+ gen STORE1(r8:lhs, DEREF1(ADD2(r16:rhs, CONSTANT():c))) { E_storeix($lhs, $rhs, $c.value); }
13091324gen STORE1(r8:lhs, DEREF1(ADD2(ADDRESS():a, r16:rhs))) { E_storeii($lhs, $rhs, &$a.sym, $a.off as uint16, 1); }
13101325
13111326gen STORE2(CONSTANT():v, DEREF2(r16:rhs)) { E_storeixc($v.value, $rhs, 0, 0); }
13121327gen STORE2(CONSTANT():v, DEREF2(ADD2(r16:rhs, CONSTANT():c))) { E_storeixc($v.value, $rhs, $c.value, 0); }
1313- gen STORE2(r16:lhs, DEREF2(r16:rhs)) { E_storeix($lhs, $rhs, 0, 0 ); }
1328+ gen STORE2(r16:lhs, DEREF2(r16:rhs)) { E_storeix($lhs, $rhs, 0); }
13141329gen STORE2(r16:lhs, DEREF2(ADDRESS():a)) { E_store($lhs, &$a.sym, $a.off, 0); }
1315- gen STORE2(r16:lhs, DEREF2(ADD2(r16:rhs, CONSTANT():c))) { E_storeix($lhs, $rhs, $c.value, 0 ); }
1330+ gen STORE2(r16:lhs, DEREF2(ADD2(r16:rhs, CONSTANT():c))) { E_storeix($lhs, $rhs, $c.value); }
13161331gen STORE2(r16:lhs, DEREF2(ADD2(ADDRESS():a, r16:rhs))) { E_storeii($lhs, $rhs, &$a.sym, $a.off as uint16, 0); }
13171332
13181333gen STORE4(r32:val, DEREF4(r16:rhs))
13191334{
1320- E_storeix(loreg($val), $rhs, 0, 0 );
1321- E_storeix(hireg($val), $rhs, 2, 0 );
1335+ E_storeix(loreg($val), $rhs, 0);
1336+ E_storeix(hireg($val), $rhs, 2);
13221337}
13231338gen STORE4(r32:val, DEREF4(ADDRESS():a))
13241339{
@@ -1334,7 +1349,7 @@ gen r32 := NEG4($$)
13341349{
13351350 E_not(hireg($$));
13361351 E_not(loreg($$));
1337- E_alu2wi ("add", 1, loreg($$)); # inc does not set the carry
1352+ E_alu2i ("add", 1, loreg($$)); # inc does not set the carry
13381353 E_adc(hireg($$));
13391354}
13401355
@@ -1494,15 +1509,16 @@ gen r32 := RSHIFTS4($$:lhs, CONSTANT():c) { E_sari4($c.value as uint8, $l
14941509gen BEQ0(CONSTANT():c1, CONSTANT():c2):b uses all { beqc(self.n[0], $c1.value, $c2.value); }
14951510
14961511gen BEQ1(r8:lhs, r8:rhs):b uses all { E_cmp($lhs, $rhs); CmpJumpsJe(self.n[0]); }
1497- gen BEQ1(r8:lhs, CONSTANT():c):b uses all { if ($c.value == 0) then E_tst($lhs); else E_cmpi($c.value, $lhs); end if ; CmpJumpsJe(self.n[0]); }
1512+ gen BEQ1(r8:lhs, CONSTANT():c):b uses all { E_cmpi($c.value, $lhs); CmpJumpsJe(self.n[0]); }
14981513gen BEQ1(AND1(r8:lhs, r8:rhs), CONSTANT(value==0)):b { E_alu2("BIT", $rhs, $lhs); CmpJumpsJe(self.n[0]); }
14991514gen BEQ1(AND1(r8:lhs, CONSTANT(value!=0):c), CONSTANT(value==0)):b
15001515{
15011516 E_alu2i("BIT", $c.value, $lhs);
15021517 CmpJumpsJe(self.n[0]);
15031518}
1519+
15041520gen BEQ2(r16:lhs, r16:rhs):b uses all { E_cmp($lhs, $rhs); CmpJumpsJe(self.n[0]); }
1505- gen BEQ2(r16:lhs, CONSTANT():c):b uses all { if ($c.value == 0) then E_tst($lhs); else E_cmpi($c.value, $lhs); end if ; CmpJumpsJe(self.n[0]); }
1521+ gen BEQ2(r16:lhs, CONSTANT():c):b uses all { E_cmpi($c.value, $lhs); CmpJumpsJe(self.n[0]); }
15061522gen BEQ2(AND2(r16:lhs, r16:rhs), CONSTANT(value==0)):b { E_alu2("BIT", $rhs, $lhs); CmpJumpsJe(self.n[0]); }
15071523gen BEQ2(AND2(r16:lhs, CONSTANT(value!=0):c), CONSTANT(value==0)):b
15081524{
0 commit comments