tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] [PATCH 08/11] riscv64-asm: Add beq, bne, blt, bge, bltu,


From: Danny Milosavljevic
Subject: [Tinycc-devel] [PATCH 08/11] riscv64-asm: Add beq, bne, blt, bge, bltu, bgeu
Date: Wed, 7 Apr 2021 13:53:11 +0200

---
 riscv64-asm.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++
 riscv64-tok.h |  9 +++++++
 2 files changed, 79 insertions(+)

diff --git a/riscv64-asm.c b/riscv64-asm.c
index 4abbc6e..27ff2cb 100644
--- a/riscv64-asm.c
+++ b/riscv64-asm.c
@@ -503,6 +503,67 @@ static void asm_data_transfer_opcode(TCCState* s1, int 
token)
     }
 }
 
+static void asm_branch_opcode(TCCState* s1, int token)
+{
+    // Branch (RS1,RS2,IMM); SB-format
+    uint32_t opcode = (0x18 << 2) | 3;
+    uint32_t offset = 0;
+    Operand ops[3];
+    parse_operand(s1, &ops[0]);
+    if (ops[0].type != OP_REG) {
+        expect("register");
+        return;
+    }
+    if (tok == ',')
+        next();
+    else
+        expect("','");
+    parse_operand(s1, &ops[1]);
+    if (ops[1].type != OP_REG) {
+        expect("register");
+        return;
+    }
+    if (tok == ',')
+        next();
+    else
+        expect("','");
+    parse_operand(s1, &ops[2]);
+
+    if (ops[2].type != OP_IM12S) {
+        tcc_error("'%s': Expected third operand that is an immediate value 
between 0 and 0xfff", get_tok_str(token, NULL));
+        return;
+    }
+    offset = ops[2].e.v;
+    if (offset & 1) {
+        tcc_error("'%s': Expected third operand that is an even immediate 
value", get_tok_str(token, NULL));
+        return;
+    }
+
+    switch (token) {
+    case TOK_ASM_beq:
+        opcode |= 0 << 12;
+        break;
+    case TOK_ASM_bne:
+        opcode |= 1 << 12;
+        break;
+    case TOK_ASM_blt:
+        opcode |= 4 << 12;
+        break;
+    case TOK_ASM_bge:
+        opcode |= 5 << 12;
+        break;
+    case TOK_ASM_bltu:
+        opcode |= 6 << 12;
+        break;
+    case TOK_ASM_bgeu:
+        opcode |= 7 << 12;
+        break;
+    default:
+        expect("known branch instruction");
+    }
+    asm_emit_opcode(opcode | ENCODE_RS1(ops[0].reg) | ENCODE_RS2(ops[1].reg) | 
(((offset >> 1) & 0xF) << 8) | (((offset >> 5) & 0x1f) << 25) | (((offset >> 
11) & 1) << 7) | (((offset >> 12) & 1) << 31));
+}
+
 ST_FUNC void asm_opcode(TCCState *s1, int token)
 {
     switch (token) {
@@ -589,6 +650,15 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
         asm_data_transfer_opcode(s1, token);
         return;
 
+    case TOK_ASM_beq:
+    case TOK_ASM_bne:
+    case TOK_ASM_blt:
+    case TOK_ASM_bge:
+    case TOK_ASM_bltu:
+    case TOK_ASM_bgeu:
+        asm_branch_opcode(s1, token);
+        return;
+
     default:
         expect("known instruction");
     }
diff --git a/riscv64-tok.h b/riscv64-tok.h
index 1261d95..0b21841 100644
--- a/riscv64-tok.h
+++ b/riscv64-tok.h
@@ -155,6 +155,15 @@
  DEF_ASM(sltu)
  DEF_ASM(sltiu)
 
+/* Branch */
+
+ DEF_ASM(beq)
+ DEF_ASM(bne)
+ DEF_ASM(blt)
+ DEF_ASM(bge)
+ DEF_ASM(bltu)
+ DEF_ASM(bgeu)
+
 /* Sync */
 
  DEF_ASM(fence)
-- 
2.29.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]