riscv64-asm: Add beq, bne, blt, bge, bltu, bgeu

This commit is contained in:
Danny Milosavljevic 2021-04-06 13:36:33 +02:00
parent 9c0760a4d4
commit b28bf50d2b
2 changed files with 79 additions and 0 deletions

View File

@ -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");
}

View File

@ -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)