---
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 a15cd75..d4d4930 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)
+{
+ 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)
{
- tcc_error("internal error: asm_opcode not implemented");
+ 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 5523299..bcbabe3 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)
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel