mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-26 03:50:07 +08:00
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
@ -132,9 +132,6 @@ static void asm_nullary_opcode(TCCState *s1, int token)
|
||||
switch (token) {
|
||||
// Sync instructions
|
||||
|
||||
case TOK_ASM_fence: // I
|
||||
asm_emit_opcode((0x3 << 2) | 3 | (0 << 12));
|
||||
return;
|
||||
case TOK_ASM_fence_i: // I
|
||||
asm_emit_opcode((0x3 << 2) | 3| (1 << 12));
|
||||
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));
|
||||
}
|
||||
|
||||
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 const Operand zero = {.type = OP_REG, .reg = 0};
|
||||
@ -1206,7 +1231,6 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
|
||||
switch (token) {
|
||||
case TOK_ASM_ebreak:
|
||||
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_hrts:
|
||||
case TOK_ASM_mrth:
|
||||
@ -1215,6 +1239,10 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
|
||||
asm_nullary_opcode(s1, token);
|
||||
return;
|
||||
|
||||
case TOK_ASM_fence:
|
||||
asm_fence_opcode(s1, token);
|
||||
return;
|
||||
|
||||
case TOK_ASM_rdcycle:
|
||||
case TOK_ASM_rdcycleh:
|
||||
case TOK_ASM_rdtime:
|
||||
|
@ -11,6 +11,9 @@
|
||||
#define DEF_ASM_WITH_SUFFIXES(x, y, z) \
|
||||
DEF(TOK_ASM_ ## x ## _ ## y ## _ ## z, #x "." #y "." #z)
|
||||
|
||||
#define DEF_ASM_FENCE(x) \
|
||||
DEF(TOK_ASM_ ## x ## _fence, #x)
|
||||
|
||||
/* register */
|
||||
/* integer */
|
||||
DEF_ASM(x0)
|
||||
@ -448,4 +451,25 @@
|
||||
DEF_ASM_WITH_SUFFIXES(sc, d, rl)
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user