[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Tinycc-devel] [PATCH 03/11] riscv64-asm: Add rdcycle, rdcycleh, rdtime,
From: |
Danny Milosavljevic |
Subject: |
[Tinycc-devel] [PATCH 03/11] riscv64-asm: Add rdcycle, rdcycleh, rdtime, rdtimeh, rdinstret, rdinstreth |
Date: |
Wed, 7 Apr 2021 13:53:06 +0200 |
---
riscv64-asm.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++
riscv64-tok.h | 9 +++++
2 files changed, 103 insertions(+)
diff --git a/riscv64-asm.c b/riscv64-asm.c
index 167d525..4a1ab1d 100644
--- a/riscv64-asm.c
+++ b/riscv64-asm.c
@@ -94,6 +94,91 @@ static void asm_nullary_opcode(TCCState *s1, int token)
}
}
+enum {
+ OPT_REG,
+ OPT_IM12S,
+ OPT_IM32,
+};
+#define OP_REG (1 << OPT_REG)
+#define OP_IM32 (1 << OPT_IM32)
+#define OP_IM12S (1 << OPT_IM12S)
+
+typedef struct Operand {
+ uint32_t type;
+ union {
+ uint8_t reg;
+ uint16_t regset;
+ ExprValue e;
+ };
+} Operand;
+
+/* Parse a text containing operand and store the result in OP */
+static void parse_operand(TCCState *s1, Operand *op)
+{
+ ExprValue e;
+ int8_t reg;
+
+ op->type = 0;
+
+ if ((reg = asm_parse_regvar(tok)) != -1) {
+ next(); // skip register name
+ op->type = OP_REG;
+ op->reg = (uint8_t) reg;
+ return;
+ } else if (tok == '$') {
+ /* constant value */
+ next(); // skip '#' or '$'
+ }
+ asm_expr(s1, &e);
+ op->type = OP_IM32;
+ op->e = e;
+ if (!op->e.sym) {
+ if ((int) op->e.v >= -2048 && (int) op->e.v < 2048)
+ op->type = OP_IM12S;
+ } else
+ expect("operand");
+}
+
+#define ENCODE_RS1(register_index) ((register_index) << 15)
+#define ENCODE_RS2(register_index) ((register_index) << 20)
+#define ENCODE_RD(register_index) ((register_index) << 7)
+
+// Note: Those all map to CSR--so they are pseudo-instructions.
+static void asm_unary_opcode(TCCState *s1, int token)
+{
+ uint32_t opcode = (0x1C << 2) | 3 | (2 << 12);
+ Operand op;
+ parse_operand(s1, &op);
+ if (op.type != OP_REG) {
+ expect("register");
+ return;
+ }
+ opcode |= ENCODE_RD(op.reg);
+
+ switch (token) {
+ case TOK_ASM_rdcycle:
+ asm_emit_opcode(opcode | (0xC00 << 20));
+ return;
+ case TOK_ASM_rdcycleh:
+ asm_emit_opcode(opcode | (0xC80 << 20));
+ return;
+ case TOK_ASM_rdtime:
+ asm_emit_opcode(opcode | (0xC01 << 20) | ENCODE_RD(op.reg));
+ return;
+ case TOK_ASM_rdtimeh:
+ asm_emit_opcode(opcode | (0xC81 << 20) | ENCODE_RD(op.reg));
+ return;
+ case TOK_ASM_rdinstret:
+ asm_emit_opcode(opcode | (0xC02 << 20) | ENCODE_RD(op.reg));
+ return;
+ case TOK_ASM_rdinstreth:
+ asm_emit_opcode(opcode | (0xC82 << 20) | ENCODE_RD(op.reg));
+ return;
+ default:
+ expect("unary instruction");
+ }
+}
+
ST_FUNC void asm_opcode(TCCState *s1, int token)
{
switch (token) {
@@ -110,6 +195,15 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
asm_nullary_opcode(s1, token);
return;
+ case TOK_ASM_rdcycle:
+ case TOK_ASM_rdcycleh:
+ case TOK_ASM_rdtime:
+ case TOK_ASM_rdtimeh:
+ case TOK_ASM_rdinstret:
+ case TOK_ASM_rdinstreth:
+ asm_unary_opcode(s1, token);
+ return;
+
default:
expect("known instruction");
}
diff --git a/riscv64-tok.h b/riscv64-tok.h
index af0e186..d6709ef 100644
--- a/riscv64-tok.h
+++ b/riscv64-tok.h
@@ -92,6 +92,15 @@
DEF_ASM(scall)
DEF_ASM(sbreak)
+/* Counters */
+
+ DEF_ASM(rdcycle)
+ DEF_ASM(rdcycleh)
+ DEF_ASM(rdtime)
+ DEF_ASM(rdtimeh)
+ DEF_ASM(rdinstret)
+ DEF_ASM(rdinstreth)
+
/* Privileged Instructions */
DEF_ASM(ecall)
--
2.29.2
- [Tinycc-devel] [PATCH 00/11] Add RISCV64 inline assembler, Danny Milosavljevic, 2021/04/07
- [Tinycc-devel] [PATCH 02/11] riscv64-asm: Add fence, fence.i, scall, sbreak, ecall, ebreak, wfi, Danny Milosavljevic, 2021/04/07
- [Tinycc-devel] [PATCH 06/11] riscv64-asm: Add add, addi, sub, addw, addd, addiw, addid, subw, subd, xor, xori, or, ori, and, andi, slt, slti, sltu, sltiu, Danny Milosavljevic, 2021/04/07
- [Tinycc-devel] [PATCH 05/11] riscv64-asm: Add sll, slli, srl, srli, sra, srai, sllw, slld, slliw, sllid, srlw, srld, srliw, srlid, sraw, srad, sraiw, sraid, Danny Milosavljevic, 2021/04/07
- [Tinycc-devel] [PATCH 07/11] riscv64-asm: Add lb, lh, lw, lbu, lhu, ld, lwu, sb, sh, sw, sd, Danny Milosavljevic, 2021/04/07
- [Tinycc-devel] [PATCH 10/11] riscv64-asm: Optimize gen_le32, Danny Milosavljevic, 2021/04/07
- [Tinycc-devel] [PATCH 01/11] riscv64-asm: Remove asm_error, Danny Milosavljevic, 2021/04/07
- [Tinycc-devel] [PATCH 03/11] riscv64-asm: Add rdcycle, rdcycleh, rdtime, rdtimeh, rdinstret, rdinstreth,
Danny Milosavljevic <=
- [Tinycc-devel] [PATCH 08/11] riscv64-asm: Add beq, bne, blt, bge, bltu, bgeu, Danny Milosavljevic, 2021/04/07
- [Tinycc-devel] [PATCH 11/11] riscv64-asm: Implement asm_clobber., Danny Milosavljevic, 2021/04/07
- [Tinycc-devel] [PATCH 09/11] riscv64-asm: Implement asm_parse_regvar, Danny Milosavljevic, 2021/04/07
- Re: [Tinycc-devel] [PATCH 09/11] riscv64-asm: Implement asm_parse_regvar, Charles Lohr, 2021/04/12
- Re: [Tinycc-devel] [PATCH 09/11] riscv64-asm: Implement asm_parse_regvar, Danny Milosavljevic, 2021/04/16
- Re: [Tinycc-devel] [PATCH 09/11] riscv64-asm: Implement asm_parse_regvar, Charles Lohr, 2021/04/16
- Re: [Tinycc-devel] [PATCH 09/11] riscv64-asm: Implement asm_parse_regvar, Danny Milosavljevic, 2021/04/23
- Re: [Tinycc-devel] [PATCH 09/11] riscv64-asm: Implement asm_parse_regvar, Christian Jullien, 2021/04/24
- Re: [Tinycc-devel] [PATCH 09/11] riscv64-asm: Implement asm_parse_regvar, Danny Milosavljevic, 2021/04/26
[Tinycc-devel] [PATCH 04/11] riscv64-asm: Add lui, auipc, Danny Milosavljevic, 2021/04/07
- Prev by Date:
[Tinycc-devel] [PATCH 01/11] riscv64-asm: Remove asm_error
- Next by Date:
[Tinycc-devel] [PATCH 08/11] riscv64-asm: Add beq, bne, blt, bge, bltu, bgeu
- Previous by thread:
[Tinycc-devel] [PATCH 01/11] riscv64-asm: Remove asm_error
- Next by thread:
[Tinycc-devel] [PATCH 08/11] riscv64-asm: Add beq, bne, blt, bge, bltu, bgeu
- Index(es):