riscv64-asm: Add beq, bne, blt, bge, bltu, bgeu
This commit is contained in:
parent
9c0760a4d4
commit
b28bf50d2b
2 changed files with 79 additions and 0 deletions
|
@ -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)
|
ST_FUNC void asm_opcode(TCCState *s1, int token)
|
||||||
{
|
{
|
||||||
switch (token) {
|
switch (token) {
|
||||||
|
@ -589,6 +650,15 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
|
||||||
asm_data_transfer_opcode(s1, token);
|
asm_data_transfer_opcode(s1, token);
|
||||||
return;
|
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:
|
default:
|
||||||
expect("known instruction");
|
expect("known instruction");
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,6 +155,15 @@
|
||||||
DEF_ASM(sltu)
|
DEF_ASM(sltu)
|
||||||
DEF_ASM(sltiu)
|
DEF_ASM(sltiu)
|
||||||
|
|
||||||
|
/* Branch */
|
||||||
|
|
||||||
|
DEF_ASM(beq)
|
||||||
|
DEF_ASM(bne)
|
||||||
|
DEF_ASM(blt)
|
||||||
|
DEF_ASM(bge)
|
||||||
|
DEF_ASM(bltu)
|
||||||
|
DEF_ASM(bgeu)
|
||||||
|
|
||||||
/* Sync */
|
/* Sync */
|
||||||
|
|
||||||
DEF_ASM(fence)
|
DEF_ASM(fence)
|
||||||
|
|
Loading…
Reference in a new issue