Unified · Split
| @@ -35,6 +35,84 @@ ST_FUNC void gen_le32(int c); · 34 unmodified lines | |||
| 35 | #define USING_GLOBALS | 35 | #define USING_GLOBALS |
| 36 | #include "tcc.h" | 36 | #include "tcc.h" |
| 37 | 37 | ||
| 38 | enum { | ||
| 39 | OPT_REG32, | ||
| 40 | OPT_REGSET32, | ||
| 41 | OPT_IM8, | ||
| 42 | OPT_IM8N, | ||
| 43 | OPT_IM32, | ||
| 44 | }; | ||
| 45 | #define OP_REG32 (1 << OPT_REG32) | ||
| 46 | #define OP_REG (OP_REG32) | ||
| 47 | #define OP_IM32 (1 << OPT_IM32) | ||
| 48 | #define OP_IM8 (1 << OPT_IM8) | ||
| 49 | #define OP_IM8N (1 << OPT_IM8N) | ||
| 50 | #define OP_REGSET32 (1 << OPT_REGSET32) | ||
| 51 | |||
| 52 | typedef struct Operand { | ||
| 53 | uint32_t type; | ||
| 54 | union { | ||
| 55 | uint8_t reg; | ||
| 56 | uint16_t regset; | ||
| 57 | ExprValue e; | ||
| 58 | }; | ||
| 59 | } Operand; | ||
| 60 | |||
| 61 | /* Parse a text containing operand and store the result in OP */ | ||
| 62 | static void parse_operand(TCCState *s1, Operand *op) | ||
| 63 | { | ||
| 64 | ExprValue e; | ||
| 65 | int8_t reg; | ||
| 66 | uint16_t regset = 0; | ||
| 67 | |||
| 68 | op->type = 0; | ||
| 69 | |||
| 70 | if (tok == '{') { // regset literal | ||
| 71 | next(); // skip '{' | ||
| 72 | while (tok != '}' && tok != TOK_EOF) { | ||
| 73 | reg = asm_parse_regvar(tok); | ||
| 74 | if (reg == -1) { | ||
| 75 | expect("register"); | ||
| 76 | return; | ||
| 77 | } else | ||
| 78 | next(); // skip register name | ||
| 79 | |||
| 80 | regset |= 1 << reg; | ||
| 81 | if (tok != ',') | ||
| 82 | break; | ||
| 83 | next(); // skip ',' | ||
| 84 | } | ||
| 85 | if (tok != '}') | ||
| 86 | expect("'}'"); | ||
| 87 | next(); // skip '}' | ||
| 88 | if (regset == 0) { | ||
| 89 | // ARM instructions don't support empty regset. | ||
| 90 | tcc_error("empty register list is not supported"); | ||
| 91 | } else { | ||
| 92 | op->type = OP_REGSET32; | ||
| 93 | op->regset = regset; | ||
| 94 | } | ||
| 95 | } else if (tok == '#' || tok == '$') { | ||
| 96 | /* constant value */ | ||
| 97 | next(); // skip '#' or '$' | ||
| 98 | asm_expr(s1, &e); | ||
| 99 | op->type = OP_IM32; | ||
| 100 | op->e = e; | ||
| 101 | if (!op->e.sym) { | ||
| 102 | if ((int) op->e.v < 0 && (int) op->e.v >= -255) | ||
| 103 | op->type = OP_IM8N; | ||
| 104 | else if (op->e.v == (uint8_t)op->e.v) | ||
| 105 | op->type = OP_IM8; | ||
| 106 | } else | ||
| 107 | expect("constant"); | ||
| 108 | } else if ((reg = asm_parse_regvar(tok)) != -1) { | ||
| 109 | next(); // skip register name | ||
| 110 | op->type = OP_REG32; | ||
| 111 | op->reg = (uint8_t) reg; | ||
| 112 | } else | ||
| 113 | expect("operand"); | ||
| 114 | } | ||
| 115 | |||
| 38 | /* XXX: make it faster ? */ | 116 | /* XXX: make it faster ? */ |
| 39 | ST_FUNC void g(int c) | 117 | ST_FUNC void g(int c) |
| 40 | { | 118 | { |
| @@ -1009,8 +1009,13 @@ redo_start: · 1008 unmodified lines | |||
| 1009 | goto redo_start; | 1009 | goto redo_start; |
| 1010 | else if (parse_flags & PARSE_FLAG_ASM_FILE) | 1010 | else if (parse_flags & PARSE_FLAG_ASM_FILE) |
| 1011 | p = parse_line_comment(p - 1); | 1011 | p = parse_line_comment(p - 1); |
| 1012 | } else if (parse_flags & PARSE_FLAG_ASM_FILE) | 1012 | } |
| 1013 | #if !defined(TCC_TARGET_ARM) | ||
| 1014 | else if (parse_flags & PARSE_FLAG_ASM_FILE) | ||
| 1013 | p = parse_line_comment(p - 1); | 1015 | p = parse_line_comment(p - 1); |
| 1016 | #else | ||
| 1017 | /* ARM assembly uses '#' for constants */ | ||
| 1018 | #endif | ||
| 1014 | break; | 1019 | break; |
| 1015 | _default: | 1020 | _default: |
| 1016 | default: | 1021 | default: |
| @@ -2703,10 +2708,13 @@ maybe_newline: · 1686 unmodified lines | |||
| 2703 | p++; | 2708 | p++; |
| 2704 | tok = TOK_TWOSHARPS; | 2709 | tok = TOK_TWOSHARPS; |
| 2705 | } else { | 2710 | } else { |
| 2711 | #if !defined(TCC_TARGET_ARM) | ||
| 2706 | if (parse_flags & PARSE_FLAG_ASM_FILE) { | 2712 | if (parse_flags & PARSE_FLAG_ASM_FILE) { |
| 2707 | p = parse_line_comment(p - 1); | 2713 | p = parse_line_comment(p - 1); |
| 2708 | goto redo_no_start; | 2714 | goto redo_no_start; |
| 2709 | } else { | 2715 | } else |
| 2716 | #endif | ||
| 2717 | { | ||
| 2710 | tok = '#'; | 2718 | tok = '#'; |
| 2711 | } | 2719 | } |
| 2712 | } | 2720 | } |