commit - db96e10e218769bf2d6506c723a0704a0e737582
commit + e2531862ff12c3ffabbcf078d1acdbd9525963ce
blob - 9885dfb8c28afe1ac754acca835805a3cbfba9d7
blob + b7d08527f09ed9cc03c721c9e4670513f1493dba
--- cc/irc/irc.c
+++ cc/irc/irc.c
EX_MUL, // .bin
EX_UDIV, // .bin
EX_SDIV, // .bin
+ EX_EQ, // .bin
+ EX_NE, // .bin
+ EX_ULT, // .bin
+ EX_UGT, // .bin
+ EX_ULE, // .bin
+ EX_UGE, // .bin
+ EX_SLT, // .bin
+ EX_SGT, // .bin
+ EX_SLE, // .bin
+ EX_SGE, // .bin
EX_PTRADD, // .bin
EX_READ, // .read
EX_CALL, // .call
assert_dt_is_int (dt);
assert_dt_is_int (&fn->regs[e->reg].dt);
+ return 0;
+}
+
+expr_cmp (fn, dt, e, t)
+struct func *fn;
+struct dtype *dt;
+struct expr *e;
+enum expr_type t;
+{
+ e->type = t;
+ expect (TK_REG);
+ e->bin.l = lval.i;
+ expect (',');
+ regimm (&e->bin.r, &default_dt);
+ expect (';');
+
+ assert_dt_is_int (&fn->regs[e->bin.l].dt);
+ assert_dt_eq (&fn->regs[e->bin.l].dt, e->bin.r.dt);
+ if (dt->type != DT_WORD)
+ error ("result of comparison must be of type word");
return 0;
}
expr_bin (fn, dt, e, EX_UDIV, 0);
} else if (strcmp (lval.s, "sdiv") == 0) {
expr_bin (fn, dt, e, EX_SDIV, 1);
+ } else if (strcmp (lval.s, "eq") == 0) {
+ expr_cmp (fn, dt, e, EX_EQ);
+ } else if (strcmp (lval.s, "ne") == 0) {
+ expr_cmp (fn, dt, e, EX_NE);
+ } else if (strcmp (lval.s, "ult") == 0) {
+ expr_cmp (fn, dt, e, EX_ULT);
+ } else if (strcmp (lval.s, "ugt") == 0) {
+ expr_cmp (fn, dt, e, EX_UGT);
+ } else if (strcmp (lval.s, "ule") == 0) {
+ expr_cmp (fn, dt, e, EX_ULE);
+ } else if (strcmp (lval.s, "uge") == 0) {
+ expr_cmp (fn, dt, e, EX_UGE);
+ } else if (strcmp (lval.s, "slt") == 0) {
+ expr_cmp (fn, dt, e, EX_SLT);
+ } else if (strcmp (lval.s, "sgt") == 0) {
+ expr_cmp (fn, dt, e, EX_SGT);
+ } else if (strcmp (lval.s, "sle") == 0) {
+ expr_cmp (fn, dt, e, EX_SLE);
+ } else if (strcmp (lval.s, "sge") == 0) {
+ expr_cmp (fn, dt, e, EX_SGE);
} else if (strcmp (lval.s, "lsl") == 0) {
expr_shift (fn, dt, e, EX_LSL);
} else if (strcmp (lval.s, "lsr") == 0) {
break;
case EX_SDIV:
printf ("sdiv $%d, ", e->bin.l);
+ print_ri (&e->bin.r);
+ break;
+ case EX_EQ:
+ printf ("eq $%d, ", e->bin.l);
+ print_ri (&e->bin.r);
+ break;
+ case EX_NE:
+ printf ("ne $%d, ", e->bin.l);
+ print_ri (&e->bin.r);
+ break;
+ case EX_ULT:
+ printf ("ult $%d, ", e->bin.l);
+ print_ri (&e->bin.r);
+ break;
+ case EX_UGT:
+ printf ("ugt $%d, ", e->bin.l);
+ print_ri (&e->bin.r);
+ break;
+ case EX_ULE:
+ printf ("ule $%d, ", e->bin.l);
+ print_ri (&e->bin.r);
+ break;
+ case EX_UGE:
+ printf ("uge $%d, ", e->bin.l);
+ print_ri (&e->bin.r);
+ break;
+ case EX_SLT:
+ printf ("slt $%d, ", e->bin.l);
+ print_ri (&e->bin.r);
+ break;
+ case EX_SGT:
+ printf ("sgt $%d, ", e->bin.l);
+ print_ri (&e->bin.r);
+ break;
+ case EX_SLE:
+ printf ("sle $%d, ", e->bin.l);
print_ri (&e->bin.r);
break;
+ case EX_SGE:
+ printf ("sge $%d, ", e->bin.l);
+ print_ri (&e->bin.r);
+ break;
case EX_PTRADD:
printf ("ptradd $%d, ", e->bin.l);
print_ri (&e->bin.r);
}
// ASM MISC
+
+int nlbl;
enum x86_reg8 {
AL,
error ("cannot use immediate values for floating-point operations");
load (NULL, acc);
load ("fdiv", &fn->regs[ri->reg]);
+ break;
+ }
+ return 0;
+}
+
+gen_cmp (fn, dt, e, cmp, cc)
+struct func *fn;
+struct dtype *dt;
+struct expr *e;
+char *cmp, *cc;
+{
+ int l1, l2;
+
+ switch (dt->type) {
+ case DT_NONE:
+ case DT_LABEL:
+ case DT_DPTR:
+ case DT_FPTR:
+ case DT_SPTR:
+ abort ();
+ break;
+
+ case DT_BYTE:
+ case DT_WORD:
+ load (NULL, &fn->regs[e->bin.l]);
+ loadri (fn, cmp, &e->bin.r);
+ goto common;
+
+ case DT_FLOAT:
+ load (NULL, &fn->regs[e->bin.l]);
+ loadri (fn, cmp, &e->bin.r);
+ goto common;
+
+ case DT_DWORD:
+ case DT_QWORD:
+ error ("comparisons not implemented for dword, qword, fptr");
+
+ common:
+ l1 = nlbl++;
+ l2 = nlbl++;
+ printf ("\tj%s .Li%d\n", cc, l1);
+ printf ("\txor ax, ax\n");
+ printf ("\tjmp .Li%d\n\n", l2);
+ printf (".Li%d:\n", l1);
+ printf ("\tmov ax, 1\n\n");
+ printf (".Li%d:\n", l2);
break;
}
return 0;
case EX_SDIV:
gen_div (fn, dt, e, 1);
break;
+ case EX_EQ:
+ gen_cmp (fn, dt, e, "test", "e");
+ break;
+ case EX_NE:
+ gen_cmp (fn, dt, e, "test", "ne");
+ break;
+ case EX_ULT:
+ gen_cmp (fn, dt, e, "cmp", "b");
+ break;
+ case EX_UGT:
+ gen_cmp (fn, dt, e, "cmp", "a");
+ break;
+ case EX_ULE:
+ gen_cmp (fn, dt, e, "cmp", "be");
+ break;
+ case EX_UGE:
+ gen_cmp (fn, dt, e, "cmp", "a");
+ break;
+ case EX_SLT:
+ gen_cmp (fn, dt, e, "cmp", "l");
+ break;
+ case EX_SGT:
+ gen_cmp (fn, dt, e, "cmp", "g");
+ break;
+ case EX_SLE:
+ gen_cmp (fn, dt, e, "cmp", "le");
+ break;
+ case EX_SGE:
+ gen_cmp (fn, dt, e, "cmp", "l");
+ break;
case EX_PTRADD:
load (NULL, &fn->regs[e->bin.l]);
{
struct ir *ir;
+ nlbl = 1;
+
printf ("section %s\n", fn->section);
if (fn->is_pub)
printf ("global %s\n", fn->name);
blob - ffe0840484c6e653a8fd2862aa41252da61d608a
blob + e8f82398186bfa8a8918662626893d6053c87ed9
--- cc/irc/test.ir
+++ cc/irc/test.ir
let $6: float = $5;
ret $0;
}
+
+fn cmp (): word {
+ let $0: word = 0;
+ let $1: word = 1;
+ let $2: word = eq $0, $1;
+ ret $2;
+}