riscv: Add full fence
instruction support
This commit adds support for `fence`'s predecessor and successor arguments.
This commit is contained in:
parent
c994068175
commit
671d03f944
2 changed files with 56 additions and 4 deletions
|
@ -132,9 +132,6 @@ static void asm_nullary_opcode(TCCState *s1, int token)
|
||||||
switch (token) {
|
switch (token) {
|
||||||
// Sync instructions
|
// Sync instructions
|
||||||
|
|
||||||
case TOK_ASM_fence: // I
|
|
||||||
asm_emit_opcode((0x3 << 2) | 3 | (0 << 12));
|
|
||||||
return;
|
|
||||||
case TOK_ASM_fence_i: // I
|
case TOK_ASM_fence_i: // I
|
||||||
asm_emit_opcode((0x3 << 2) | 3| (1 << 12));
|
asm_emit_opcode((0x3 << 2) | 3| (1 << 12));
|
||||||
return;
|
return;
|
||||||
|
@ -435,6 +432,34 @@ static void asm_emit_u(int token, uint32_t opcode, const Operand* rd, const Oper
|
||||||
gen_le32(opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12));
|
gen_le32(opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_fence_operand(){
|
||||||
|
int t = tok;
|
||||||
|
if ( tok == TOK_ASM_or ){
|
||||||
|
// we are in a fence instruction, parse as output read
|
||||||
|
t = TOK_ASM_or_fence;
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
return t - (TOK_ASM_w_fence - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asm_fence_opcode(TCCState *s1, int token){
|
||||||
|
// `fence` is both an instruction and a pseudoinstruction:
|
||||||
|
// `fence` expands to `fence iorw, iorw`
|
||||||
|
int succ = 0xF, pred = 0xF;
|
||||||
|
if (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF){
|
||||||
|
pred = parse_fence_operand();
|
||||||
|
if ( pred > 0xF || pred < 0) {
|
||||||
|
tcc_error("'%s': Expected first operand that is a valid predecessor operand", get_tok_str(token, NULL));
|
||||||
|
}
|
||||||
|
if ( tok == ',') next(); else expect("','");
|
||||||
|
succ = parse_fence_operand();
|
||||||
|
if ( succ > 0xF || succ < 0) {
|
||||||
|
tcc_error("'%s': Expected second operand that is a valid successor operand", get_tok_str(token, NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
asm_emit_opcode((0x3 << 2) | 3 | (0 << 12) | succ<<20 | pred<<24);
|
||||||
|
}
|
||||||
|
|
||||||
static void asm_binary_opcode(TCCState* s1, int token)
|
static void asm_binary_opcode(TCCState* s1, int token)
|
||||||
{
|
{
|
||||||
static const Operand zero = {.type = OP_REG, .reg = 0};
|
static const Operand zero = {.type = OP_REG, .reg = 0};
|
||||||
|
@ -1206,7 +1231,6 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case TOK_ASM_ebreak:
|
case TOK_ASM_ebreak:
|
||||||
case TOK_ASM_ecall:
|
case TOK_ASM_ecall:
|
||||||
case TOK_ASM_fence: // XXX: it's missing iorw for pred and succ
|
|
||||||
case TOK_ASM_fence_i:
|
case TOK_ASM_fence_i:
|
||||||
case TOK_ASM_hrts:
|
case TOK_ASM_hrts:
|
||||||
case TOK_ASM_mrth:
|
case TOK_ASM_mrth:
|
||||||
|
@ -1215,6 +1239,10 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
|
||||||
asm_nullary_opcode(s1, token);
|
asm_nullary_opcode(s1, token);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case TOK_ASM_fence:
|
||||||
|
asm_fence_opcode(s1, token);
|
||||||
|
return;
|
||||||
|
|
||||||
case TOK_ASM_rdcycle:
|
case TOK_ASM_rdcycle:
|
||||||
case TOK_ASM_rdcycleh:
|
case TOK_ASM_rdcycleh:
|
||||||
case TOK_ASM_rdtime:
|
case TOK_ASM_rdtime:
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
#define DEF_ASM_WITH_SUFFIXES(x, y, z) \
|
#define DEF_ASM_WITH_SUFFIXES(x, y, z) \
|
||||||
DEF(TOK_ASM_ ## x ## _ ## y ## _ ## z, #x "." #y "." #z)
|
DEF(TOK_ASM_ ## x ## _ ## y ## _ ## z, #x "." #y "." #z)
|
||||||
|
|
||||||
|
#define DEF_ASM_FENCE(x) \
|
||||||
|
DEF(TOK_ASM_ ## x ## _fence, #x)
|
||||||
|
|
||||||
/* register */
|
/* register */
|
||||||
/* integer */
|
/* integer */
|
||||||
DEF_ASM(x0)
|
DEF_ASM(x0)
|
||||||
|
@ -448,4 +451,25 @@
|
||||||
DEF_ASM_WITH_SUFFIXES(sc, d, rl)
|
DEF_ASM_WITH_SUFFIXES(sc, d, rl)
|
||||||
DEF_ASM_WITH_SUFFIXES(sc, d, aqrl)
|
DEF_ASM_WITH_SUFFIXES(sc, d, aqrl)
|
||||||
|
|
||||||
|
/* `fence` arguments */
|
||||||
|
/* NOTE: Order is important */
|
||||||
|
DEF_ASM_FENCE(w)
|
||||||
|
DEF_ASM_FENCE(r)
|
||||||
|
DEF_ASM_FENCE(rw)
|
||||||
|
|
||||||
|
DEF_ASM_FENCE(o)
|
||||||
|
DEF_ASM_FENCE(ow)
|
||||||
|
DEF_ASM_FENCE(or)
|
||||||
|
DEF_ASM_FENCE(orw)
|
||||||
|
|
||||||
|
DEF_ASM_FENCE(i)
|
||||||
|
DEF_ASM_FENCE(iw)
|
||||||
|
DEF_ASM_FENCE(ir)
|
||||||
|
DEF_ASM_FENCE(irw)
|
||||||
|
|
||||||
|
DEF_ASM_FENCE(io)
|
||||||
|
DEF_ASM_FENCE(iow)
|
||||||
|
DEF_ASM_FENCE(ior)
|
||||||
|
DEF_ASM_FENCE(iorw)
|
||||||
|
|
||||||
#undef DEF_ASM_WITH_SUFFIX
|
#undef DEF_ASM_WITH_SUFFIX
|
||||||
|
|
Loading…
Reference in a new issue