arm-asm: Add parse_operand, Operand
tccpp: Allow '#' token to reach the assembler.
This commit is contained in:
parent
a16678e9f3
commit
c5428cd19c
2 changed files with 88 additions and 2 deletions
78
arm-asm.c
78
arm-asm.c
|
@ -35,6 +35,84 @@ ST_FUNC void gen_le32(int c);
|
||||||
#define USING_GLOBALS
|
#define USING_GLOBALS
|
||||||
#include "tcc.h"
|
#include "tcc.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
OPT_REG32,
|
||||||
|
OPT_REGSET32,
|
||||||
|
OPT_IM8,
|
||||||
|
OPT_IM8N,
|
||||||
|
OPT_IM32,
|
||||||
|
};
|
||||||
|
#define OP_REG32 (1 << OPT_REG32)
|
||||||
|
#define OP_REG (OP_REG32)
|
||||||
|
#define OP_IM32 (1 << OPT_IM32)
|
||||||
|
#define OP_IM8 (1 << OPT_IM8)
|
||||||
|
#define OP_IM8N (1 << OPT_IM8N)
|
||||||
|
#define OP_REGSET32 (1 << OPT_REGSET32)
|
||||||
|
|
||||||
|
typedef struct Operand {
|
||||||
|
uint32_t type;
|
||||||
|
union {
|
||||||
|
uint8_t reg;
|
||||||
|
uint16_t regset;
|
||||||
|
ExprValue e;
|
||||||
|
};
|
||||||
|
} Operand;
|
||||||
|
|
||||||
|
/* Parse a text containing operand and store the result in OP */
|
||||||
|
static void parse_operand(TCCState *s1, Operand *op)
|
||||||
|
{
|
||||||
|
ExprValue e;
|
||||||
|
int8_t reg;
|
||||||
|
uint16_t regset = 0;
|
||||||
|
|
||||||
|
op->type = 0;
|
||||||
|
|
||||||
|
if (tok == '{') { // regset literal
|
||||||
|
next(); // skip '{'
|
||||||
|
while (tok != '}' && tok != TOK_EOF) {
|
||||||
|
reg = asm_parse_regvar(tok);
|
||||||
|
if (reg == -1) {
|
||||||
|
expect("register");
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
next(); // skip register name
|
||||||
|
|
||||||
|
regset |= 1 << reg;
|
||||||
|
if (tok != ',')
|
||||||
|
break;
|
||||||
|
next(); // skip ','
|
||||||
|
}
|
||||||
|
if (tok != '}')
|
||||||
|
expect("'}'");
|
||||||
|
next(); // skip '}'
|
||||||
|
if (regset == 0) {
|
||||||
|
// ARM instructions don't support empty regset.
|
||||||
|
tcc_error("empty register list is not supported");
|
||||||
|
} else {
|
||||||
|
op->type = OP_REGSET32;
|
||||||
|
op->regset = regset;
|
||||||
|
}
|
||||||
|
} else if (tok == '#' || tok == '$') {
|
||||||
|
/* constant value */
|
||||||
|
next(); // skip '#' or '$'
|
||||||
|
asm_expr(s1, &e);
|
||||||
|
op->type = OP_IM32;
|
||||||
|
op->e = e;
|
||||||
|
if (!op->e.sym) {
|
||||||
|
if ((int) op->e.v < 0 && (int) op->e.v >= -255)
|
||||||
|
op->type = OP_IM8N;
|
||||||
|
else if (op->e.v == (uint8_t)op->e.v)
|
||||||
|
op->type = OP_IM8;
|
||||||
|
} else
|
||||||
|
expect("constant");
|
||||||
|
} else if ((reg = asm_parse_regvar(tok)) != -1) {
|
||||||
|
next(); // skip register name
|
||||||
|
op->type = OP_REG32;
|
||||||
|
op->reg = (uint8_t) reg;
|
||||||
|
} else
|
||||||
|
expect("operand");
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX: make it faster ? */
|
/* XXX: make it faster ? */
|
||||||
ST_FUNC void g(int c)
|
ST_FUNC void g(int c)
|
||||||
{
|
{
|
||||||
|
|
12
tccpp.c
12
tccpp.c
|
@ -1009,8 +1009,13 @@ redo_start:
|
||||||
goto redo_start;
|
goto redo_start;
|
||||||
else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
||||||
p = parse_line_comment(p - 1);
|
p = parse_line_comment(p - 1);
|
||||||
} else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
}
|
||||||
|
#if !defined(TCC_TARGET_ARM)
|
||||||
|
else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
||||||
p = parse_line_comment(p - 1);
|
p = parse_line_comment(p - 1);
|
||||||
|
#else
|
||||||
|
/* ARM assembly uses '#' for constants */
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
_default:
|
_default:
|
||||||
default:
|
default:
|
||||||
|
@ -2703,10 +2708,13 @@ maybe_newline:
|
||||||
p++;
|
p++;
|
||||||
tok = TOK_TWOSHARPS;
|
tok = TOK_TWOSHARPS;
|
||||||
} else {
|
} else {
|
||||||
|
#if !defined(TCC_TARGET_ARM)
|
||||||
if (parse_flags & PARSE_FLAG_ASM_FILE) {
|
if (parse_flags & PARSE_FLAG_ASM_FILE) {
|
||||||
p = parse_line_comment(p - 1);
|
p = parse_line_comment(p - 1);
|
||||||
goto redo_no_start;
|
goto redo_no_start;
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
tok = '#';
|
tok = '#';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue