riscv64-asm.c: add support for calculating addresses of symbols
add some pseudoinstructions
riscv64-tok.h: add pseudoinstructions from tables 25.{2,3}
			
			
This commit is contained in:
		
							parent
							
								
									b390feec6d
								
							
						
					
					
						commit
						ada17a08eb
					
				
					 2 changed files with 83 additions and 5 deletions
				
			
		| 
						 | 
					@ -167,6 +167,7 @@ static void asm_nullary_opcode(TCCState *s1, int token)
 | 
				
			||||||
static void parse_operand(TCCState *s1, Operand *op)
 | 
					static void parse_operand(TCCState *s1, Operand *op)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ExprValue e = {0};
 | 
					    ExprValue e = {0};
 | 
				
			||||||
 | 
					    Sym label = {0};
 | 
				
			||||||
    int8_t reg;
 | 
					    int8_t reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    op->type = 0;
 | 
					    op->type = 0;
 | 
				
			||||||
| 
						 | 
					@ -190,6 +191,19 @@ static void parse_operand(TCCState *s1, Operand *op)
 | 
				
			||||||
    if (!op->e.sym) {
 | 
					    if (!op->e.sym) {
 | 
				
			||||||
        if (op->e.v < 0x1000)
 | 
					        if (op->e.v < 0x1000)
 | 
				
			||||||
            op->type = OP_IM12S;
 | 
					            op->type = OP_IM12S;
 | 
				
			||||||
 | 
					    } else if (op->e.sym->type.t & (VT_EXTERN | VT_STATIC)) {
 | 
				
			||||||
 | 
					        label.type.t = VT_VOID | VT_STATIC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* use the medium PIC model: GOT, auipc, lw */
 | 
				
			||||||
 | 
					        if (op->e.sym->type.t & VT_STATIC)
 | 
				
			||||||
 | 
					            greloca(cur_text_section, op->e.sym, ind, R_RISCV_PCREL_HI20, 0);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            greloca(cur_text_section, op->e.sym, ind, R_RISCV_GOT_HI20, 0);
 | 
				
			||||||
 | 
					        put_extern_sym(&label, cur_text_section, ind, 0);
 | 
				
			||||||
 | 
					        greloca(cur_text_section, &label, ind+4, R_RISCV_PCREL_LO12_I, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        op->type = OP_IM12S;
 | 
				
			||||||
 | 
					        op->e.v = 0;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        expect("operand");
 | 
					        expect("operand");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -206,6 +220,7 @@ static void asm_unary_opcode(TCCState *s1, int token)
 | 
				
			||||||
    opcode |= ENCODE_RD(op.reg);
 | 
					    opcode |= ENCODE_RD(op.reg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (token) {
 | 
					    switch (token) {
 | 
				
			||||||
 | 
					    /* pseudoinstructions */
 | 
				
			||||||
    case TOK_ASM_rdcycle:
 | 
					    case TOK_ASM_rdcycle:
 | 
				
			||||||
        asm_emit_opcode(opcode | (0xC00 << 20));
 | 
					        asm_emit_opcode(opcode | (0xC00 << 20));
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
| 
						 | 
					@ -224,6 +239,7 @@ static void asm_unary_opcode(TCCState *s1, int token)
 | 
				
			||||||
    case TOK_ASM_rdinstreth:
 | 
					    case TOK_ASM_rdinstreth:
 | 
				
			||||||
        asm_emit_opcode(opcode | (0xC82 << 20) | ENCODE_RD(op.reg));
 | 
					        asm_emit_opcode(opcode | (0xC82 << 20) | ENCODE_RD(op.reg));
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					    /* C extension */
 | 
				
			||||||
    case TOK_ASM_c_j:
 | 
					    case TOK_ASM_c_j:
 | 
				
			||||||
        asm_emit_cj(token, 1 | (5 << 13), &op);
 | 
					        asm_emit_cj(token, 1 | (5 << 13), &op);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
| 
						 | 
					@ -375,6 +391,21 @@ static void asm_binary_opcode(TCCState* s1, int token)
 | 
				
			||||||
        asm_emit_css(token, 2 | (5 << 13), ops, ops + 1);
 | 
					        asm_emit_css(token, 2 | (5 << 13), ops, ops + 1);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* pseudoinstructions */
 | 
				
			||||||
 | 
					    /* rd, sym */
 | 
				
			||||||
 | 
					    case TOK_ASM_la:
 | 
				
			||||||
 | 
					        /* auipc rd, 0 */
 | 
				
			||||||
 | 
					        asm_emit_u(token, 3 | (5 << 2), ops, ops + 1);
 | 
				
			||||||
 | 
					        /* lw rd, rd, 0 */
 | 
				
			||||||
 | 
					        asm_emit_i(token, 3 | (2 << 12), ops, ops, ops + 1);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    case TOK_ASM_lla:
 | 
				
			||||||
 | 
					        /* auipc rd, 0 */
 | 
				
			||||||
 | 
					        asm_emit_u(token, 3 | (5 << 2), ops, ops + 1);
 | 
				
			||||||
 | 
					        /* addi rd, rd, 0 */
 | 
				
			||||||
 | 
					        asm_emit_i(token, 3 | (4 << 2), ops, ops, ops + 1);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        expect("binary instruction");
 | 
					        expect("binary instruction");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -807,7 +838,6 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
 | 
				
			||||||
    case TOK_ASM_hrts:
 | 
					    case TOK_ASM_hrts:
 | 
				
			||||||
    case TOK_ASM_mrth:
 | 
					    case TOK_ASM_mrth:
 | 
				
			||||||
    case TOK_ASM_mrts:
 | 
					    case TOK_ASM_mrts:
 | 
				
			||||||
    case TOK_ASM_nop:
 | 
					 | 
				
			||||||
    case TOK_ASM_wfi:
 | 
					    case TOK_ASM_wfi:
 | 
				
			||||||
        asm_nullary_opcode(s1, token);
 | 
					        asm_nullary_opcode(s1, token);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
| 
						 | 
					@ -952,6 +982,16 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
 | 
				
			||||||
        asm_ternary_opcode(s1, token);
 | 
					        asm_ternary_opcode(s1, token);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* pseudoinstructions */
 | 
				
			||||||
 | 
					    case TOK_ASM_nop:
 | 
				
			||||||
 | 
					        asm_nullary_opcode(s1, token);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case TOK_ASM_la:
 | 
				
			||||||
 | 
					    case TOK_ASM_lla:
 | 
				
			||||||
 | 
					        asm_binary_opcode(s1, token);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        expect("known instruction");
 | 
					        expect("known instruction");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -244,10 +244,6 @@
 | 
				
			||||||
 DEF_ASM(rdinstret)
 | 
					 DEF_ASM(rdinstret)
 | 
				
			||||||
 DEF_ASM(rdinstreth)
 | 
					 DEF_ASM(rdinstreth)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* no operation */
 | 
					 | 
				
			||||||
 DEF_ASM(nop)
 | 
					 | 
				
			||||||
 DEF_ASM_WITH_SUFFIX(c, nop)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* “M” Standard Extension for Integer Multiplication and Division, V2.0 */
 | 
					/* “M” Standard Extension for Integer Multiplication and Division, V2.0 */
 | 
				
			||||||
 DEF_ASM(mul)
 | 
					 DEF_ASM(mul)
 | 
				
			||||||
 DEF_ASM(mulh)
 | 
					 DEF_ASM(mulh)
 | 
				
			||||||
| 
						 | 
					@ -265,6 +261,7 @@
 | 
				
			||||||
 DEF_ASM(remuw)
 | 
					 DEF_ASM(remuw)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* "C" Extension for Compressed Instructions, V2.0 */
 | 
					/* "C" Extension for Compressed Instructions, V2.0 */
 | 
				
			||||||
 | 
					 DEF_ASM_WITH_SUFFIX(c, nop)
 | 
				
			||||||
/* Loads */
 | 
					/* Loads */
 | 
				
			||||||
 DEF_ASM_WITH_SUFFIX(c, li)
 | 
					 DEF_ASM_WITH_SUFFIX(c, li)
 | 
				
			||||||
 DEF_ASM_WITH_SUFFIX(c, lw)
 | 
					 DEF_ASM_WITH_SUFFIX(c, lw)
 | 
				
			||||||
| 
						 | 
					@ -360,8 +357,10 @@
 | 
				
			||||||
 DEF_ASM(csrw)
 | 
					 DEF_ASM(csrw)
 | 
				
			||||||
 DEF_ASM(csrwi)
 | 
					 DEF_ASM(csrwi)
 | 
				
			||||||
 DEF_ASM(frcsr)
 | 
					 DEF_ASM(frcsr)
 | 
				
			||||||
 | 
					 DEF_ASM(frflags)
 | 
				
			||||||
 DEF_ASM(frrm)
 | 
					 DEF_ASM(frrm)
 | 
				
			||||||
 DEF_ASM(fscsr)
 | 
					 DEF_ASM(fscsr)
 | 
				
			||||||
 | 
					 DEF_ASM(fsflags)
 | 
				
			||||||
 DEF_ASM(fsrm)
 | 
					 DEF_ASM(fsrm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Privileged Instructions */
 | 
					/* Privileged Instructions */
 | 
				
			||||||
| 
						 | 
					@ -371,4 +370,43 @@
 | 
				
			||||||
 DEF_ASM(hrts)
 | 
					 DEF_ASM(hrts)
 | 
				
			||||||
 DEF_ASM(wfi)
 | 
					 DEF_ASM(wfi)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* pseudoinstructions */
 | 
				
			||||||
 | 
					 DEF_ASM(beqz)
 | 
				
			||||||
 | 
					 DEF_ASM(bgez)
 | 
				
			||||||
 | 
					 DEF_ASM(bgt)
 | 
				
			||||||
 | 
					 DEF_ASM(bgtu)
 | 
				
			||||||
 | 
					 DEF_ASM(bgtz)
 | 
				
			||||||
 | 
					 DEF_ASM(ble)
 | 
				
			||||||
 | 
					 DEF_ASM(bleu)
 | 
				
			||||||
 | 
					 DEF_ASM(blez)
 | 
				
			||||||
 | 
					 DEF_ASM(bltz)
 | 
				
			||||||
 | 
					 DEF_ASM(bnez)
 | 
				
			||||||
 | 
					 DEF_ASM(call)
 | 
				
			||||||
 | 
					 DEF_ASM_WITH_SUFFIX(fabs, d)
 | 
				
			||||||
 | 
					 DEF_ASM_WITH_SUFFIX(fabs, s)
 | 
				
			||||||
 | 
					 DEF_ASM(fld)
 | 
				
			||||||
 | 
					 DEF_ASM(flw)
 | 
				
			||||||
 | 
					 DEF_ASM_WITH_SUFFIX(fmv, d)
 | 
				
			||||||
 | 
					 DEF_ASM_WITH_SUFFIX(fmv, s)
 | 
				
			||||||
 | 
					 DEF_ASM_WITH_SUFFIX(fneg, d)
 | 
				
			||||||
 | 
					 DEF_ASM_WITH_SUFFIX(fneg, s)
 | 
				
			||||||
 | 
					 DEF_ASM(fsd)
 | 
				
			||||||
 | 
					 DEF_ASM(fsw)
 | 
				
			||||||
 | 
					 DEF_ASM(j)
 | 
				
			||||||
 | 
					 DEF_ASM(la)
 | 
				
			||||||
 | 
					 DEF_ASM(li)
 | 
				
			||||||
 | 
					 DEF_ASM(lla)
 | 
				
			||||||
 | 
					 DEF_ASM(mv)
 | 
				
			||||||
 | 
					 DEF_ASM(neg)
 | 
				
			||||||
 | 
					 DEF_ASM(negw)
 | 
				
			||||||
 | 
					 DEF_ASM(nop)
 | 
				
			||||||
 | 
					 DEF_ASM(not)
 | 
				
			||||||
 | 
					 DEF_ASM(ret)
 | 
				
			||||||
 | 
					 DEF_ASM(seqz)
 | 
				
			||||||
 | 
					 DEF_ASM_WITH_SUFFIX(sext, w)
 | 
				
			||||||
 | 
					 DEF_ASM(sgtz)
 | 
				
			||||||
 | 
					 DEF_ASM(sltz)
 | 
				
			||||||
 | 
					 DEF_ASM(snez)
 | 
				
			||||||
 | 
					 DEF_ASM(tail)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef DEF_ASM_WITH_SUFFIX
 | 
					#undef DEF_ASM_WITH_SUFFIX
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue