aboutsummaryrefslogtreecommitdiff
path: root/tasm/src
diff options
context:
space:
mode:
Diffstat (limited to 'tasm/src')
-rw-r--r--tasm/src/assembler.c9
-rw-r--r--tasm/src/lexer.l1
-rw-r--r--tasm/src/parser.y9
3 files changed, 15 insertions, 4 deletions
diff --git a/tasm/src/assembler.c b/tasm/src/assembler.c
index 731a736..ba61045 100644
--- a/tasm/src/assembler.c
+++ b/tasm/src/assembler.c
@@ -378,9 +378,16 @@ static void fix_reloc_b(struct asm_ctx *ctx, size_t ro, size_t so)
ctx->buf[ro] = build_s(OPCODE_BRANCH, hi, fn0, rs1, rs2, lo);
}
+/* convert instruction index (as used by ctx->idx) to addresses */
+static size_t asm_addr(size_t o)
+{
+ return o * 3;
+}
+
static void fix_reloc_j(struct asm_ctx *ctx, size_t ro, size_t so)
{
- int64_t off = so - ctx->idx;
+ /* internal offsets are instruction indexes, so convert to address */
+ int64_t off = asm_addr(so) - asm_addr(ro);
tri_t t = tri_from(off);
if (tri_mask(t, 18) != t) {
fprintf(stderr, "jump offset at %llu too large\n",
diff --git a/tasm/src/lexer.l b/tasm/src/lexer.l
index 01a4bee..cf63cfe 100644
--- a/tasm/src/lexer.l
+++ b/tasm/src/lexer.l
@@ -181,6 +181,7 @@ str \"(\\.|[^"\\])*\"
"pcall" {return pcall;}
"fence" {return fence;}
"nop" {return nop; /* meta */}
+"mv" {return mv;}
"li" {return li;}
"la" {return la;}
diff --git a/tasm/src/parser.y b/tasm/src/parser.y
index a39c9c1..204fe0a 100644
--- a/tasm/src/parser.y
+++ b/tasm/src/parser.y
@@ -73,7 +73,7 @@
%token ecall ebreak pcall
%token fence
/* meta */
-%token li la nop
+%token mv li la nop
/* m (avoid name clash with stdlib div) */
%token mul diV rem
@@ -292,8 +292,8 @@ i
{emit_reloc(ctx, RELOC_J, $4);
emit_u(ctx, OPCODE_JAL, $2, 0);}
- | jalr gpr "," gpr "," imm
- {emit_i(ctx, OPCODE_JALR, $2, 0, $4, $6);}
+ | jalr gpr "," imm "(" gpr ")"
+ {emit_i(ctx, OPCODE_JALR, $2, 0, $6, $4);}
| beq gpr "," gpr "," addr
{emit_reloc(ctx, RELOC_B, $6);
@@ -337,6 +337,9 @@ i
{emit_d(ctx, OPCODE_DIOP, $2, $4, $6, check_nop3($8));}
/* meta */
+ | mv gpr "," gpr
+ {emit_i(ctx, OPCODE_OP_IMM, $2, OP_IMM_ADDI, $4, 0);}
+
| nop
{emit_i(ctx, OPCODE_OP_IMM, X0_NUM, OP_IMM_ADDI, X0_NUM, 0);}