commit 82f7044d260ba86c4ed3b94c90f95ef93a3424da from: Benjamin Stürz date: Wed Oct 02 21:42:55 2024 UTC irc: allow EX_{ADD,SUB} for DT_FLOAT commit - 39fac2eaebd5440c562cbf2bfcde2295a43e64d1 commit + 82f7044d260ba86c4ed3b94c90f95ef93a3424da blob - 2d93d40f2460306e7d326eceab8a13425f394ff5 blob + 9504f77484f3e758af98278e26a2ff6c7a1a2a2a --- cc/irc/irc.c +++ cc/irc/irc.c @@ -465,6 +465,25 @@ struct dtype *dt; return 0; } +assert_dt_is_num (dt) +struct dtype *dt; +{ + switch (dt->type) { + case DT_BYTE: + case DT_WORD: + case DT_DWORD: + case DT_QWORD: + case DT_FLOAT: + return 0; + case DT_NONE: + case DT_LABEL: + case DT_DPTR: + case DT_FPTR: + case DT_SPTR: + return error ("this operation is only supported for numbers (byte, word, dword, qword, float)"); + } +} + assert_dt_is_int (dt) struct dtype *dt; { @@ -574,7 +593,7 @@ struct dtype *dt; return 0; } -expr_bin (fn, dt, e, t) +expr_bin (fn, dt, e, t, allow_float) struct func *fn; struct dtype *dt; struct expr *e; @@ -589,7 +608,11 @@ struct expr *e; assert_dt_eq (dt, &fn->regs[e->bin.l].dt); assert_dt_eq (dt, e->bin.r.dt); - assert_dt_is_int (dt); + if (allow_float) { + assert_dt_is_num (dt); + } else { + assert_dt_is_int (dt); + } return 0; } @@ -692,21 +715,21 @@ struct expr *e; e->alloca.off = fn->stoff; expect (';'); } else if (strcmp (lval.s, "add") == 0) { - expr_bin (fn, dt, e, EX_ADD); + expr_bin (fn, dt, e, EX_ADD, 1); } else if (strcmp (lval.s, "sub") == 0) { - expr_bin (fn, dt, e, EX_SUB); + expr_bin (fn, dt, e, EX_SUB, 1); } else if (strcmp (lval.s, "and") == 0) { - expr_bin (fn, dt, e, EX_AND); + expr_bin (fn, dt, e, EX_AND, 0); } else if (strcmp (lval.s, "or") == 0) { - expr_bin (fn, dt, e, EX_OR); + expr_bin (fn, dt, e, EX_OR, 0); } else if (strcmp (lval.s, "xor") == 0) { - expr_bin (fn, dt, e, EX_XOR); + expr_bin (fn, dt, e, EX_XOR, 0); } else if (strcmp (lval.s, "mul") == 0) { - expr_bin (fn, dt, e, EX_MUL); - } else if (strcmp (lval.s, "udiv") == 0) { - expr_bin (fn, dt, e, EX_UDIV); + expr_bin (fn, dt, e, EX_MUL, 0); + } else if (strcmp (lval.s, "udiv") == 0) { + expr_bin (fn, dt, e, EX_UDIV, 0); } else if (strcmp (lval.s, "sdiv") == 0) { - expr_bin (fn, dt, e, EX_SDIV); + expr_bin (fn, dt, e, EX_SDIV, 0); } else if (strcmp (lval.s, "lsl") == 0) { expr_shift (fn, dt, e, EX_LSL); } else if (strcmp (lval.s, "lsr") == 0) { @@ -1520,7 +1543,7 @@ long imm; loadimmr (instr, "cx", (imm >> 48) & 0xffff); break; case DT_FLOAT: - abort (); + error ("cannot use immediate values for floating-point operations"); break; } return 0; @@ -1575,8 +1598,8 @@ char *reg; return 0; } -addsub (instr1, instrn, fn, dt, e) -char *instr1, *instrn; +addsub (instr1, instrn, instrf, fn, dt, e) +char *instr1, *instrn, *instrf; struct func *fn; struct dtype *dt; struct expr *e; @@ -1600,11 +1623,13 @@ struct expr *e; loadpwri (fn, instrn, DX, &e->bin.r, 2); loadpwri (fn, instrn, BX, &e->bin.r, 4); loadpwri (fn, instrn, CX, &e->bin.r, 6); + break; + case DT_FLOAT: + loadri (fn, instrf, &e->bin.r); break; case DT_DPTR: case DT_FPTR: case DT_SPTR: - case DT_FLOAT: error ("cannot add/sub pointers or floats"); break; } @@ -1903,10 +1928,10 @@ struct expr *e; } break; case EX_ADD: - addsub ("add", "adc", fn, dt, e); + addsub ("add", "adc", "fadd", fn, dt, e); break; case EX_SUB: - addsub ("sub", "sbb", fn, dt, e); + addsub ("sub", "sbb", "fsubr", fn, dt, e); break; case EX_AND: alu ("and", fn, dt, e); blob - e96a05542ef6c37eea0a5ef7fa790be2eef47717 blob + db86c91d6e1dc50b6a6904583a518e608eb3ce78 --- cc/irc/test.ir +++ cc/irc/test.ir @@ -200,5 +200,7 @@ fn floats (): float { let $4: float = fmul $0, $1; let $5: float = fdiv $0, $1; let $6: float = $5; + let $7: float = add $0, $1; + let $8: float = sub $0, $1; ret $0; }