From 9295e8f445dae6431f8e7c543eb8c374742b136d Mon Sep 17 00:00:00 2001 From: Kimplul Date: Tue, 9 Apr 2024 20:32:48 +0300 Subject: add constant value to some instructions --- include/qbt/nodes.h | 9 ++++--- src/abi.c | 13 +++++----- src/asm.c | 2 +- src/correct.c | 8 +++---- src/nodes.c | 4 ++-- src/parser.y | 69 ++++++++++++++++++++++++++--------------------------- src/regalloc.c | 8 +++++-- tests/3.qbt | 2 +- 8 files changed, 61 insertions(+), 54 deletions(-) diff --git a/include/qbt/nodes.h b/include/qbt/nodes.h index 718a83a..b8c601b 100644 --- a/include/qbt/nodes.h +++ b/include/qbt/nodes.h @@ -133,6 +133,7 @@ struct insn { struct val out; struct val in[2]; enum insn_flags flags; + long long v; }; static inline void set_insn_flags(struct insn *i, enum insn_flags flags) @@ -261,13 +262,15 @@ static inline bool same_val(struct val v1, struct val v2) static inline struct insn insn_create(enum insn_type o, enum val_type t, struct val r, struct val a0, - struct val a1) + struct val a1, + long long v) { return (struct insn) { .type = o, .vtype = t, .out = r, - .in = {a0, a1} + .in = {a0, a1}, + .v = v, }; } @@ -275,7 +278,7 @@ int64_t idalloc(struct fn *f, const char *id); int64_t idmatch(struct fn *f, const char *id); void insadd(struct blk *b, enum insn_type o, enum val_type t, struct val r, - struct val a0, struct val a1); + struct val a0, struct val a1, long long v); void finish_block(struct blk *b, enum insn_type cmp, struct val a0, struct val a1, const char *label); diff --git a/src/abi.c b/src/abi.c index a16ef2d..76d3e74 100644 --- a/src/abi.c +++ b/src/abi.c @@ -21,7 +21,7 @@ static struct insn rewrite_param(struct insn n) assert(nth_param >= 0 && nth_param < 25 && "stack argument passing not yet supported"); - return insn_create(MOVE, I27, n.out, nth_ar(nth_param), noclass()); + return insn_create(MOVE, I27, n.out, nth_ar(nth_param), noclass(), 0); } static struct insn rewrite_retval(struct insn n) @@ -30,7 +30,7 @@ static struct insn rewrite_retval(struct insn n) assert(n.in[1].class == IMM); int64_t nth_retval = n.in[1].v; assert(nth_retval >= 0 && nth_retval < 25); - n = insn_create(MOVE, I27, n.out, nth_ar(nth_retval), noclass()); + n = insn_create(MOVE, I27, n.out, nth_ar(nth_retval), noclass(), 0); set_insn_flags(&n, CALL_TEARDOWN); return n; } @@ -44,13 +44,13 @@ static struct insn rewrite_arg(struct insn n) if (n.in[0].class == TMP || n.in[0].class == REG) { n = insn_create(MOVE, I27, nth_ar(nth_arg), n.in[0], - noclass()); + noclass(), 0); set_insn_flags(&n, CALL_SETUP); return n; } else if (n.in[0].class == IMM || n.in[0].class == REF) { n = insn_create(COPY, I27, nth_ar(nth_arg), n.in[0], - noclass()); + noclass(), 0); set_insn_flags(&n, CALL_SETUP); return n; } @@ -68,10 +68,11 @@ static struct insn rewrite_retarg(struct insn n) if (n.in[0].class == TMP || n.in[0].class == REG) return insn_create(MOVE, I27, nth_ar(nth_arg), n.in[0], - noclass()); + noclass(), 0); + else if (n.in[0].class == IMM || n.in[0].class == REF) return insn_create(COPY, I27, nth_ar(nth_arg), n.in[0], - noclass()); + noclass(), 0); assert("illegal retval type"); abort(); diff --git a/src/asm.c b/src/asm.c index e4b65cc..0491a0f 100644 --- a/src/asm.c +++ b/src/asm.c @@ -392,7 +392,7 @@ static void output_moves(struct vec *params, struct vec *args, FILE *o) foreach_blk_param(pi, *params) { struct val p = blk_param_at(*params, pi); struct val a = blk_param_at(*args, pi); - struct insn i = insn_create(MOVE, NOTYPE, p, a, noclass()); + struct insn i = insn_create(MOVE, NOTYPE, p, a, noclass(), 0); output_move(i, o); } } diff --git a/src/correct.c b/src/correct.c index 2654218..9191ff9 100644 --- a/src/correct.c +++ b/src/correct.c @@ -3,7 +3,7 @@ static size_t spill_ref(struct blk *b, size_t ii, struct insn i, size_t idx, size_t ri) { struct val tmp = tmp_val(ri++); - struct insn new = insn_create(ADDR, I27, tmp, i.in[idx], noclass()); + struct insn new = insn_create(ADDR, I27, tmp, i.in[idx], noclass(), 0); i.in[idx] = tmp; insn_at(b->insns, ii) = i; insn_insert(b, new, ii); @@ -13,7 +13,7 @@ static size_t spill_ref(struct blk *b, size_t ii, struct insn i, size_t idx, siz static size_t spill_imm(struct blk *b, size_t ii, struct insn i, size_t idx, size_t ri) { struct val tmp = tmp_val(ri++); - struct insn new = insn_create(COPY, I27, tmp, i.in[idx], noclass()); + struct insn new = insn_create(COPY, I27, tmp, i.in[idx], noclass(), 0); i.in[idx] = tmp; insn_at(b->insns, ii) = i; insn_insert(b, new, ii); @@ -125,13 +125,13 @@ void correct(struct fn *f, size_t ri) if (b->cmp[0].class == IMM) { struct val t = tmp_val(ri++); - insadd(b, COPY, I27, t, b->cmp[0], noclass()); + insadd(b, COPY, I27, t, b->cmp[0], noclass(), 0); b->cmp[0] = t; } if (b->cmp[1].class == IMM) { struct val t = tmp_val(ri++); - insadd(b, COPY, I27, t, b->cmp[0], noclass()); + insadd(b, COPY, I27, t, b->cmp[0], noclass(), 0); b->cmp[1] = t; } } diff --git a/src/nodes.c b/src/nodes.c index 22fc454..07a1706 100644 --- a/src/nodes.c +++ b/src/nodes.c @@ -7,9 +7,9 @@ #include void insadd(struct blk *b, enum insn_type o, enum val_type t, struct val r, - struct val a0, struct val a1) + struct val a0, struct val a1, long long v) { - struct insn i = insn_create(o, t, r, a0, a1); + struct insn i = insn_create(o, t, r, a0, a1, v); vec_append(&b->insns, &i); } diff --git a/src/parser.y b/src/parser.y index bda8f31..c0653bd 100644 --- a/src/parser.y +++ b/src/parser.y @@ -172,9 +172,10 @@ static inline void do_insadd(struct parser *p, enum val_type t, struct val r, struct val a0, - struct val a1) + struct val a1, + long long v) { - insadd(p->b, cmp, t, r, a0, a1); + insadd(p->b, cmp, t, r, a0, a1, v); } static inline void do_new_function(struct parser *p, const char *name) @@ -220,8 +221,8 @@ static inline void do_ins_replace(struct parser *p, size_t i, struct insn n) #define CUR_INSN()\ do_cur_insn(parser) -#define INSADD(o, t, r, a0, a1)\ - do_insadd(parser, o, t, r, a0, a1) +#define INSADD(o, t, r, a0, a1, v)\ + do_insadd(parser, o, t, r, a0, a1, v) #define IDALLOC(i)\ do_idalloc(parser, i) @@ -278,7 +279,7 @@ data param : type id { struct val t = IDALLOC($[id]); - INSADD(PARAM, $[type], t, noclass(), imm_val(parser->idx++, I27)); + INSADD(PARAM, $[type], t, noclass(), imm_val(parser->idx++, I27), 0); } params @@ -312,23 +313,23 @@ arg arith : type id "=" arg "+" arg { struct val t = IDALLOC($[id]); - INSADD(ADD, $[type], t, $4, $6); + INSADD(ADD, $[type], t, $4, $6, 0); } | type id "=" arg "-" arg { struct val t = IDALLOC($[id]); - INSADD(SUB, $[type], t, $4, $6); + INSADD(SUB, $[type], t, $4, $6, 0); } | type id "=" arg "*" arg { struct val t = IDALLOC($[id]); - INSADD(MUL, $[type], t, $4, $6); + INSADD(MUL, $[type], t, $4, $6, 0); } | type id "=" arg "/" arg { struct val t = IDALLOC($[id]); - INSADD(DIV, $[type], t, $4, $6); + INSADD(DIV, $[type], t, $4, $6, 0); } | type id "=" arg "%" arg { struct val t = IDALLOC($[id]); - INSADD(REM, $[type], t, $4, $6); + INSADD(REM, $[type], t, $4, $6, 0); } addr @@ -337,18 +338,18 @@ addr imm : type id "=" int { struct val t = IDALLOC($[id]); - INSADD(COPY, $[type], t, imm_val($[int], I27), noclass()); + INSADD(COPY, $[type], t, imm_val($[int], I27), noclass(), 0); } | type id "=" addr { struct val t = IDALLOC($[id]); - INSADD(COPY, $[type], t, imm_ref($[addr]), noclass()); + INSADD(COPY, $[type], t, imm_ref($[addr]), noclass(), 0); } move : type id "=" id { struct val t = IDALLOC($2); struct val f = IDTOVAL($4); - INSADD(MOVE, $[type], t, f, noclass()); + INSADD(MOVE, $[type], t, f, noclass(), 0); } mem_base @@ -361,65 +362,63 @@ mem : type id "<<" mem_base mem_off { struct val t = IDTOVAL($[id]); struct val b = IDTOVAL($[mem_base]); - struct val o = imm_val($[mem_off], I27); - INSADD(LOAD, $[type], t, b, o); + INSADD(LOAD, $[type], t, b, noclass(), $[mem_off]); } | id ">>" type mem_base mem_off { struct val t = IDTOVAL($[id]); struct val b = IDTOVAL($[mem_base]); - struct val o = imm_val($[mem_off], I27); /* really not a huge fan or 'reusing' the output slot... */ - INSADD(STORE, $[type], o, b, t); + INSADD(STORE, $[type], noclass(), b, t, $[mem_off]); } stack : type id "=" "alloc" int { struct val t = IDALLOC($[id]); - INSADD(ALLOC, $[type], t, imm_val($[int], I27), noclass()); + INSADD(ALLOC, $[type], t, noclass(), noclass(), $[int]); } cond : type id "=" arg "==" arg { struct val t = IDALLOC($[id]); - INSADD(EQ, $[type], t, $4, $6); + INSADD(EQ, $[type], t, $4, $6, 0); } | type id "=" arg "!=" arg { struct val t = IDALLOC($[id]); - INSADD(NE, $[type], t, $4, $6); + INSADD(NE, $[type], t, $4, $6, 0); } | type id "=" arg "<=" arg { struct val t = IDALLOC($[id]); - INSADD(LE, $[type], t, $4, $6); + INSADD(LE, $[type], t, $4, $6, 0); } | type id "=" arg ">=" arg { struct val t = IDALLOC($[id]); - INSADD(GE, $[type], t, $4, $6); + INSADD(GE, $[type], t, $4, $6, 0); } | type id "=" arg "<" arg { struct val t = IDALLOC($[id]); - INSADD(LT, $[type], t, $4, $6); + INSADD(LT, $[type], t, $4, $6, 0); } | type id "=" arg ">" arg { struct val t = IDALLOC($[id]); - INSADD(GT, $[type], t, $4, $6); + INSADD(GT, $[type], t, $4, $6, 0); } logic : type id "=" "!" arg { struct val t = IDALLOC($[id]); - INSADD(NOT, $[type], t, $5, noclass()); + INSADD(NOT, $[type], t, $5, noclass(), 0); } | type id "=" "-" arg { struct val t = IDALLOC($[id]); - INSADD(NEG, $[type], t, $5, noclass()); + INSADD(NEG, $[type], t, $5, noclass(), 0); } | type id "=" arg "<<" arg { struct val t = IDALLOC($[id]); - INSADD(LSHIFT, $[type], t, $4, $6); + INSADD(LSHIFT, $[type], t, $4, $6, 0); } | type id "=" arg ">>" arg { struct val t = IDALLOC($[id]); - INSADD(RSHIFT, $[type], t, $4, $6); + INSADD(RSHIFT, $[type], t, $4, $6, 0); } local @@ -461,7 +460,7 @@ ret call_ret : ret { - INSADD(RETVAL, NOTYPE, $[ret], noclass(), imm_val(parser->idx++, I27)); + INSADD(RETVAL, NOTYPE, $[ret], noclass(), imm_val(parser->idx++, I27), 0); } call_rets @@ -474,8 +473,8 @@ opt_call_rets | {} call_arg - : arg { - INSADD(ARG, NOTYPE, noclass(), $[arg], imm_val(parser->idx++, I27)); + : type arg { + INSADD(ARG, $[type], noclass(), $[arg], imm_val(parser->idx++, I27), 0); } call_args @@ -494,7 +493,7 @@ reset_index placeholder : { $$ = CUR_INSN(); - INSADD(CALL, NOTYPE, noclass(), noclass(), noclass()); + INSADD(CALL, NOTYPE, noclass(), noclass(), noclass(), 0); } call @@ -503,18 +502,18 @@ call /* kind of hacky but works */ INS_REPLACE($[placeholder], insn_create(CALL, NOTYPE, - noclass(), imm_ref($[addr]), noclass())); + noclass(), imm_ref($[addr]), noclass(), 0)); } | id reset_index "(" opt_call_args ")" "=>" placeholder reset_index "(" opt_call_rets ")" { INS_REPLACE($[placeholder], insn_create(CALL, NOTYPE, - noclass(), IDTOVAL($[id]), noclass())); + noclass(), IDTOVAL($[id]), noclass(), 0)); } proc_ret : id { - INSADD(RETARG, NOTYPE, noclass(), IDTOVAL($[id]), imm_val(parser->idx++, I27)); + INSADD(RETARG, NOTYPE, noclass(), IDTOVAL($[id]), imm_val(parser->idx++, I27), 0); } proc_rets diff --git a/src/regalloc.c b/src/regalloc.c index 9c4d87e..f5157fe 100644 --- a/src/regalloc.c +++ b/src/regalloc.c @@ -447,7 +447,9 @@ static size_t do_call_saves(struct blk *b, struct vec *lifetimes, struct vec *rm continue; struct insn save = insn_create(SAVE, NOTYPE, - noclass(), r, imm_val(counter, I27)); + noclass(), r, + imm_val(counter, I27), 0); + insn_insert_before_call(b, save, call_pos + offset - 1); offset++; counter++; @@ -465,7 +467,9 @@ static size_t do_call_saves(struct blk *b, struct vec *lifetimes, struct vec *rm /* hmm, restore should maybe put r as its output to be * more consistent... */ struct insn restore = insn_create(RESTORE, NOTYPE, - noclass(), r, imm_val(counter, I27)); + noclass(), r, + imm_val(counter, I27), 0); + insn_insert_after_call(b, restore, call_pos - 1); counter++; offset++; diff --git a/tests/3.qbt b/tests/3.qbt index 7d3217a..bba7c31 100644 --- a/tests/3.qbt +++ b/tests/3.qbt @@ -6,7 +6,7 @@ main() top: i27 sum = sum + i; - i27 i = i + i27 1; + i27 i = i + 1; i < max -> top; &_putchar(sum) => (); => (); -- cgit v1.3