From aaf052391d5243435b6bd4f23419105459438742 Mon Sep 17 00:00:00 2001 From: Danny Milosavljevic Date: Sat, 26 Dec 2020 16:39:31 +0100 Subject: [PATCH] arm-asm: Add nop --- arm-asm.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- arm-tok.h | 25 +++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/arm-asm.c b/arm-asm.c index a15cd758..d4d4930e 100644 --- a/arm-asm.c +++ b/arm-asm.c @@ -31,6 +31,7 @@ ST_FUNC void gen_le32(int c); /*************************************************************/ #else /*************************************************************/ + #define USING_GLOBALS #include "tcc.h" @@ -64,9 +65,48 @@ ST_FUNC void gen_expr32(ExprValue *pe) gen_le32(pe->v); } -ST_FUNC void asm_opcode(TCCState *s1, int opcode) +static uint32_t condition_code_of_token(int token) { + if (token < TOK_ASM_nopeq) { + expect("instruction"); + return 0; + } else + return (token - TOK_ASM_nopeq) & 15; +} + +static void asm_emit_opcode(int token, uint32_t opcode) { + gen_le32((condition_code_of_token(token) << 28) | opcode); +} + +static void asm_nullary_opcode(int token) { - tcc_error("internal error: asm_opcode not implemented"); + switch (ARM_INSTRUCTION_GROUP(token)) { + case TOK_ASM_nopeq: + asm_emit_opcode(token, 0xd << 21); // mov r0, r0 + break; + default: + expect("nullary instruction"); + } +} + +ST_FUNC void asm_opcode(TCCState *s1, int token) +{ + while (token == TOK_LINEFEED) { + next(); + token = tok; + } + if (token == TOK_EOF) + return; + if (token < TOK_ASM_nopeq) { + expect("instruction"); + return; + } + + switch (ARM_INSTRUCTION_GROUP(token)) { + case TOK_ASM_nopeq: + return asm_nullary_opcode(token); + default: + expect("known instruction"); + } } ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) diff --git a/arm-tok.h b/arm-tok.h index 55232997..bcbabe3a 100644 --- a/arm-tok.h +++ b/arm-tok.h @@ -27,3 +27,28 @@ DEF_ASM(sp) /* alias for r13 */ DEF_ASM(lr) /* alias for r14 */ DEF_ASM(pc) /* alias for r15 */ + +#define ARM_INSTRUCTION_GROUP(tok) ((((tok) - TOK_ASM_nopeq) & 0xFFFFFFF0) + TOK_ASM_nopeq) + +/* Note: condition code is 4 bits */ +#define DEF_ASM_CONDED(x) \ + DEF(TOK_ASM_ ## x ## eq, #x "eq") \ + DEF(TOK_ASM_ ## x ## ne, #x "ne") \ + DEF(TOK_ASM_ ## x ## cs, #x "cs") \ + DEF(TOK_ASM_ ## x ## cc, #x "cc") \ + DEF(TOK_ASM_ ## x ## mi, #x "mi") \ + DEF(TOK_ASM_ ## x ## pl, #x "pl") \ + DEF(TOK_ASM_ ## x ## vs, #x "vs") \ + DEF(TOK_ASM_ ## x ## vc, #x "vc") \ + DEF(TOK_ASM_ ## x ## hi, #x "hi") \ + DEF(TOK_ASM_ ## x ## ls, #x "ls") \ + DEF(TOK_ASM_ ## x ## ge, #x "ge") \ + DEF(TOK_ASM_ ## x ## lt, #x "lt") \ + DEF(TOK_ASM_ ## x ## gt, #x "gt") \ + DEF(TOK_ASM_ ## x ## le, #x "le") \ + DEF(TOK_ASM_ ## x, #x) \ + DEF(TOK_ASM_ ## x ## rsvd, #x "rsvd") + +/* Note: add new tokens after nop (MUST always use DEF_ASM_CONDED) */ + + DEF_ASM_CONDED(nop)