Before: ld rd, rs, imm sd rs1, rs2, imm Now: ld rd, imm(rs) sd rs2, imm(rs1)
Unified · Split
| @@ -63,6 +63,7 @@ static void asm_unary_opcode(TCCState *s1, int token); · 62 unmodified lines | ||
| 63 | 63 | ST_FUNC void gen_expr32(ExprValue *pe); |
| 64 | 64 | static void parse_operand(TCCState *s1, Operand *op); |
| 65 | 65 | static void parse_operands(TCCState *s1, Operand *ops, int count); |
| 66 | +static void parse_mem_access_operands(TCCState *s1, Operand* ops); | |
| 66 | 67 | ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier); |
| 67 | 68 | /* C extension */ |
| 68 | 69 | static void asm_emit_ca(int token, uint16_t opcode, const Operand *rd, const Operand *rs2); |
| @@ -223,6 +224,43 @@ static void parse_operands(TCCState *s1, Operand* ops, int count){ · 154 unmodified lines | ||
| 223 | 224 | } |
| 224 | 225 | } |
| 225 | 226 | |
| 227 | +/* parse `X, imm(Y)` to {X, Y, imm} operands */ | |
| 228 | +static void parse_mem_access_operands(TCCState *s1, Operand* ops){ | |
| 229 | + static const Operand zimm = {.type = OP_IM12S}; | |
| 230 | + | |
| 231 | + Operand op; | |
| 232 | + int i; | |
| 233 | + | |
| 234 | + parse_operand(s1, &ops[0]); | |
| 235 | + if ( tok == ',') | |
| 236 | + next(); | |
| 237 | + else | |
| 238 | + expect("','"); | |
| 239 | + | |
| 240 | + if ( tok == '(') { | |
| 241 | + /* `X, (Y)` case*/ | |
| 242 | + next(); | |
| 243 | + parse_operand(s1, &ops[1]); | |
| 244 | + if ( tok == ')') next(); else expect("')'"); | |
| 245 | + ops[2] = zimm; | |
| 246 | + } else { | |
| 247 | + parse_operand(s1, &ops[2]); | |
| 248 | + if ( tok == '('){ | |
| 249 | + /* `X, imm(Y)` case*/ | |
| 250 | + next(); | |
| 251 | + parse_operand(s1, &ops[1]); | |
| 252 | + if ( tok == ')') next(); else expect("')'"); | |
| 253 | + } else { | |
| 254 | + /* `X, Y` case*/ | |
| 255 | + /* we parsed Y thinking it was imm, swap and default imm to zero */ | |
| 256 | + op = ops[2]; | |
| 257 | + ops[1] = ops[2]; | |
| 258 | + ops[2] = op; | |
| 259 | + ops[2] = zimm; | |
| 260 | + } | |
| 261 | + } | |
| 262 | +} | |
| 263 | + | |
| 226 | 264 | static void asm_unary_opcode(TCCState *s1, int token) |
| 227 | 265 | { |
| 228 | 266 | uint32_t opcode = (0x1C << 2) | 3 | (2 << 12); |
| @@ -505,6 +543,52 @@ static void asm_emit_j(int token, uint32_t opcode, const Operand* rd, const Oper · 276 unmodified lines | ||
| 505 | 543 | gen_le32(opcode | ENCODE_RD(rd->reg) | (((imm >> 20) & 1) << 31) | (((imm >> 1) & 0x3ff) << 21) | (((imm >> 11) & 1) << 20) | (((imm >> 12) & 0xff) << 12)); |
| 506 | 544 | } |
| 507 | 545 | |
| 546 | +static void asm_mem_access_opcode(TCCState *s1, int token) | |
| 547 | +{ | |
| 548 | + | |
| 549 | + Operand ops[3]; | |
| 550 | + parse_mem_access_operands(s1, &ops[0]); | |
| 551 | + | |
| 552 | + // l{b|h|w|d}[u] rd, imm(rs1); I-format | |
| 553 | + switch (token) { | |
| 554 | + case TOK_ASM_lb: | |
| 555 | + asm_emit_i(token, (0x0 << 2) | 3, &ops[0], &ops[1], &ops[2]); | |
| 556 | + return; | |
| 557 | + case TOK_ASM_lh: | |
| 558 | + asm_emit_i(token, (0x0 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); | |
| 559 | + return; | |
| 560 | + case TOK_ASM_lw: | |
| 561 | + asm_emit_i(token, (0x0 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); | |
| 562 | + return; | |
| 563 | + case TOK_ASM_ld: | |
| 564 | + asm_emit_i(token, (0x0 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); | |
| 565 | + return; | |
| 566 | + case TOK_ASM_lbu: | |
| 567 | + asm_emit_i(token, (0x0 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); | |
| 568 | + return; | |
| 569 | + case TOK_ASM_lhu: | |
| 570 | + asm_emit_i(token, (0x0 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); | |
| 571 | + return; | |
| 572 | + case TOK_ASM_lwu: | |
| 573 | + asm_emit_i(token, (0x0 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]); | |
| 574 | + return; | |
| 575 | + | |
| 576 | + // s{b|h|w|d} rs2, imm(rs1); S-format (with rsX swapped) | |
| 577 | + case TOK_ASM_sb: | |
| 578 | + asm_emit_s(token, (0x8 << 2) | 3 | (0 << 12), &ops[1], &ops[0], &ops[2]); | |
| 579 | + return; | |
| 580 | + case TOK_ASM_sh: | |
| 581 | + asm_emit_s(token, (0x8 << 2) | 3 | (1 << 12), &ops[1], &ops[0], &ops[2]); | |
| 582 | + return; | |
| 583 | + case TOK_ASM_sw: | |
| 584 | + asm_emit_s(token, (0x8 << 2) | 3 | (2 << 12), &ops[1], &ops[0], &ops[2]); | |
| 585 | + return; | |
| 586 | + case TOK_ASM_sd: | |
| 587 | + asm_emit_s(token, (0x8 << 2) | 3 | (3 << 12), &ops[1], &ops[0], &ops[2]); | |
| 588 | + return; | |
| 589 | + } | |
| 590 | +} | |
| 591 | + | |
| 508 | 592 | static void asm_ternary_opcode(TCCState *s1, int token) |
| 509 | 593 | { |
| 510 | 594 | Operand ops[3]; |
| @@ -630,46 +714,6 @@ static void asm_ternary_opcode(TCCState *s1, int token) · 119 unmodified lines | ||
| 630 | 714 | asm_emit_b(token, 0x63 | (7 << 12), ops, ops + 1, ops + 2); |
| 631 | 715 | return; |
| 632 | 716 | |
| 633 | − // Loads (RD,RS1,I); I-format | |
| 634 | − | |
| 635 | − case TOK_ASM_lb: | |
| 636 | − asm_emit_i(token, (0x0 << 2) | 3, &ops[0], &ops[1], &ops[2]); | |
| 637 | − return; | |
| 638 | − case TOK_ASM_lh: | |
| 639 | − asm_emit_i(token, (0x0 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); | |
| 640 | − return; | |
| 641 | − case TOK_ASM_lw: | |
| 642 | − asm_emit_i(token, (0x0 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); | |
| 643 | − return; | |
| 644 | − case TOK_ASM_lbu: | |
| 645 | − asm_emit_i(token, (0x0 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); | |
| 646 | − return; | |
| 647 | − case TOK_ASM_lhu: | |
| 648 | − asm_emit_i(token, (0x0 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); | |
| 649 | − return; | |
| 650 | − // 64 bit | |
| 651 | − case TOK_ASM_ld: | |
| 652 | − asm_emit_i(token, (0x0 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); | |
| 653 | − return; | |
| 654 | − case TOK_ASM_lwu: | |
| 655 | − asm_emit_i(token, (0x0 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]); | |
| 656 | − return; | |
| 657 | − | |
| 658 | − // Stores (RS1,RS2,I); S-format | |
| 659 | − | |
| 660 | − case TOK_ASM_sb: | |
| 661 | − asm_emit_s(token, (0x8 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]); | |
| 662 | − return; | |
| 663 | − case TOK_ASM_sh: | |
| 664 | − asm_emit_s(token, (0x8 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); | |
| 665 | − return; | |
| 666 | − case TOK_ASM_sw: | |
| 667 | − asm_emit_s(token, (0x8 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); | |
| 668 | − return; | |
| 669 | − case TOK_ASM_sd: | |
| 670 | − asm_emit_s(token, (0x8 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); | |
| 671 | − return; | |
| 672 | − | |
| 673 | 717 | /* M extension */ |
| 674 | 718 | case TOK_ASM_div: |
| 675 | 719 | asm_emit_r(token, 0x33 | (4 << 12) | (1 << 25), ops, ops + 1, ops + 2); |
| @@ -856,6 +900,20 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 180 unmodified lines | ||
| 856 | 900 | asm_binary_opcode(s1, token); |
| 857 | 901 | return; |
| 858 | 902 | |
| 903 | + case TOK_ASM_lb: | |
| 904 | + case TOK_ASM_lh: | |
| 905 | + case TOK_ASM_lw: | |
| 906 | + case TOK_ASM_ld: | |
| 907 | + case TOK_ASM_lbu: | |
| 908 | + case TOK_ASM_lhu: | |
| 909 | + case TOK_ASM_lwu: | |
| 910 | + case TOK_ASM_sb: | |
| 911 | + case TOK_ASM_sh: | |
| 912 | + case TOK_ASM_sw: | |
| 913 | + case TOK_ASM_sd: | |
| 914 | + asm_mem_access_opcode(s1, token); | |
| 915 | + break; | |
| 916 | + | |
| 859 | 917 | case TOK_ASM_add: |
| 860 | 918 | case TOK_ASM_addi: |
| 861 | 919 | case TOK_ASM_addiw: |
| @@ -869,18 +927,8 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 7 unmodified lines | ||
| 869 | 927 | case TOK_ASM_bltu: |
| 870 | 928 | case TOK_ASM_bne: |
| 871 | 929 | case TOK_ASM_jalr: |
| 872 | − case TOK_ASM_lb: | |
| 873 | − case TOK_ASM_lbu: | |
| 874 | − case TOK_ASM_ld: | |
| 875 | − case TOK_ASM_lh: | |
| 876 | − case TOK_ASM_lhu: | |
| 877 | − case TOK_ASM_lw: | |
| 878 | − case TOK_ASM_lwu: | |
| 879 | 930 | case TOK_ASM_or: |
| 880 | 931 | case TOK_ASM_ori: |
| 881 | − case TOK_ASM_sb: | |
| 882 | − case TOK_ASM_sd: | |
| 883 | − case TOK_ASM_sh: | |
| 884 | 932 | case TOK_ASM_sll: |
| 885 | 933 | case TOK_ASM_slli: |
| 886 | 934 | case TOK_ASM_slliw: |
| @@ -899,7 +947,6 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 12 unmodified lines | ||
| 899 | 947 | case TOK_ASM_srlw: |
| 900 | 948 | case TOK_ASM_sub: |
| 901 | 949 | case TOK_ASM_subw: |
| 902 | − case TOK_ASM_sw: | |
| 903 | 950 | case TOK_ASM_xor: |
| 904 | 951 | case TOK_ASM_xori: |
| 905 | 952 | /* M extension */ |