Unified · Split
| @@ -272,18 +272,25 @@ static void asm_jal_opcode(TCCState *s1, int token){ · 271 unmodified lines | |||
| 272 | static const Operand ra = {.type = OP_REG, .reg = 1}; | 272 | static const Operand ra = {.type = OP_REG, .reg = 1}; |
| 273 | Operand ops[2]; | 273 | Operand ops[2]; |
| 274 | parse_operand(s1, &ops[0]); | 274 | parse_operand(s1, &ops[0]); |
| 275 | if ( tok == ',') | 275 | if ( ops[0].type != OP_REG ) { |
| 276 | next(); | ||
| 277 | else { | ||
| 278 | /* no more operands, it's the pseudoinstruction: | 276 | /* no more operands, it's the pseudoinstruction: |
| 279 | * jal rs | 277 | * jal offset |
| 280 | * Expand to: | 278 | * Expand to: |
| 281 | * jal ra, rs | 279 | * jal ra, offset |
| 282 | */ | 280 | */ |
| 283 | asm_emit_j(token, 0x6f, &ra, &ops[0]); | 281 | ops[1] = ops[0]; |
| 284 | return; | 282 | ops[0] = ra; |
| 283 | goto emit; | ||
| 285 | } | 284 | } |
| 285 | if ( tok == ',') | ||
| 286 | next(); | ||
| 287 | else | ||
| 288 | expect("','"); | ||
| 286 | parse_operand(s1, &ops[1]); | 289 | parse_operand(s1, &ops[1]); |
| 290 | emit: | ||
| 291 | if (ops[1].e.sym && ops[1].e.sym->type.t & (VT_EXTERN | VT_STATIC)){ | ||
| 292 | greloca(cur_text_section, ops[1].e.sym, ind, R_RISCV_JAL, 0); | ||
| 293 | } | ||
| 287 | asm_emit_j(token, 0x6f, &ops[0], &ops[1]); | 294 | asm_emit_j(token, 0x6f, &ops[0], &ops[1]); |
| 288 | } | 295 | } |
| 289 | 296 | ||
| @@ -722,7 +729,7 @@ static void asm_emit_j(int token, uint32_t opcode, const Operand* rd, const Oper · 432 unmodified lines | |||
| 722 | imm = rs2->e.v; | 729 | imm = rs2->e.v; |
| 723 | 730 | ||
| 724 | /* even offsets in a +- 1 MiB range */ | 731 | /* even offsets in a +- 1 MiB range */ |
| 725 | if (imm > 0x1ffffe) { | 732 | if ((int)imm > (1 << 20) -1 || (int)imm <= -1 * ((1 << 20) -1)) { |
| 726 | tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0x1fffff", get_tok_str(token, NULL)); | 733 | tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0x1fffff", get_tok_str(token, NULL)); |
| 727 | return; | 734 | return; |
| 728 | } | 735 | } |