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 | ST_FUNC void gen_expr32(ExprValue *pe); | 63 | ST_FUNC void gen_expr32(ExprValue *pe); |
| 64 | static void parse_operand(TCCState *s1, Operand *op); | 64 | static void parse_operand(TCCState *s1, Operand *op); |
| 65 | static void parse_operands(TCCState *s1, Operand *ops, int count); | 65 | static void parse_operands(TCCState *s1, Operand *ops, int count); |
| 66 | static void parse_mem_access_operands(TCCState *s1, Operand* ops); | ||
| 66 | ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier); | 67 | ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier); |
| 67 | /* C extension */ | 68 | /* C extension */ |
| 68 | static void asm_emit_ca(int token, uint16_t opcode, const Operand *rd, const Operand *rs2); | 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 | static void asm_unary_opcode(TCCState *s1, int token) | 264 | static void asm_unary_opcode(TCCState *s1, int token) |
| 227 | { | 265 | { |
| 228 | uint32_t opcode = (0x1C << 2) | 3 | (2 << 12); | 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 | gen_le32(opcode | ENCODE_RD(rd->reg) | (((imm >> 20) & 1) << 31) | (((imm >> 1) & 0x3ff) << 21) | (((imm >> 11) & 1) << 20) | (((imm >> 12) & 0xff) << 12)); | 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 | static void asm_ternary_opcode(TCCState *s1, int token) | 592 | static void asm_ternary_opcode(TCCState *s1, int token) |
| 509 | { | 593 | { |
| 510 | Operand ops[3]; | 594 | Operand ops[3]; |
| @@ -630,46 +714,6 @@ static void asm_ternary_opcode(TCCState *s1, int token) · 119 unmodified lines | |||
| 630 | asm_emit_b(token, 0x63 | (7 << 12), ops, ops + 1, ops + 2); | 714 | asm_emit_b(token, 0x63 | (7 << 12), ops, ops + 1, ops + 2); |
| 631 | return; | 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 | /* M extension */ | 717 | /* M extension */ |
| 674 | case TOK_ASM_div: | 718 | case TOK_ASM_div: |
| 675 | asm_emit_r(token, 0x33 | (4 << 12) | (1 << 25), ops, ops + 1, ops + 2); | 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 | asm_binary_opcode(s1, token); | 900 | asm_binary_opcode(s1, token); |
| 857 | return; | 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 | case TOK_ASM_add: | 917 | case TOK_ASM_add: |
| 860 | case TOK_ASM_addi: | 918 | case TOK_ASM_addi: |
| 861 | case TOK_ASM_addiw: | 919 | case TOK_ASM_addiw: |
| @@ -869,18 +927,8 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 7 unmodified lines | |||
| 869 | case TOK_ASM_bltu: | 927 | case TOK_ASM_bltu: |
| 870 | case TOK_ASM_bne: | 928 | case TOK_ASM_bne: |
| 871 | case TOK_ASM_jalr: | 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 | case TOK_ASM_or: | 930 | case TOK_ASM_or: |
| 880 | case TOK_ASM_ori: | 931 | case TOK_ASM_ori: |
| 881 | case TOK_ASM_sb: | ||
| 882 | case TOK_ASM_sd: | ||
| 883 | case TOK_ASM_sh: | ||
| 884 | case TOK_ASM_sll: | 932 | case TOK_ASM_sll: |
| 885 | case TOK_ASM_slli: | 933 | case TOK_ASM_slli: |
| 886 | case TOK_ASM_slliw: | 934 | case TOK_ASM_slliw: |
| @@ -899,7 +947,6 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 12 unmodified lines | |||
| 899 | case TOK_ASM_srlw: | 947 | case TOK_ASM_srlw: |
| 900 | case TOK_ASM_sub: | 948 | case TOK_ASM_sub: |
| 901 | case TOK_ASM_subw: | 949 | case TOK_ASM_subw: |
| 902 | case TOK_ASM_sw: | ||
| 903 | case TOK_ASM_xor: | 950 | case TOK_ASM_xor: |
| 904 | case TOK_ASM_xori: | 951 | case TOK_ASM_xori: |
| 905 | /* M extension */ | 952 | /* M extension */ |