History

arm-asm: Add parse_operand, Operand

Danny Milosavljevic committed 5 years ago

Commit c5428cd1 parent a16678e2 files · +88 −2Browse files

Unified · Split

2 files
  1. arm-asm.c +78 −0
  2. tccpp.c +10 −2
arm-asm.c+78−0
@@ -35,6 +35,84 @@ ST_FUNC void gen_le32(int c); · 34 unmodified lines
3535 #define USING_GLOBALS
3636 #include "tcc.h"
3737
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+
38116 /* XXX: make it faster ? */
39117 ST_FUNC void g(int c)
40118 {
tccpp.c+10−2
@@ -1009,8 +1009,13 @@ redo_start: · 1008 unmodified lines
10091009 goto redo_start;
10101010 else if (parse_flags & PARSE_FLAG_ASM_FILE)
10111011 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)
10131015 p = parse_line_comment(p - 1);
1016+#else
1017+ /* ARM assembly uses '#' for constants */
1018+#endif
10141019 break;
10151020 _default:
10161021 default:
@@ -2703,10 +2708,13 @@ maybe_newline: · 1686 unmodified lines
27032708 p++;
27042709 tok = TOK_TWOSHARPS;
27052710 } else {
2711+#if !defined(TCC_TARGET_ARM)
27062712 if (parse_flags & PARSE_FLAG_ASM_FILE) {
27072713 p = parse_line_comment(p - 1);
27082714 goto redo_no_start;
2709− } else {
2715+ } else
2716+#endif
2717+ {
27102718 tok = '#';
27112719 }
27122720 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t