tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] [PATCH 08/16] arm-asm: Add push, pop


From: Danny Milosavljevic
Subject: [Tinycc-devel] [PATCH 08/16] arm-asm: Add push, pop
Date: Sat, 26 Dec 2020 22:58:09 +0100

Also edited tcctok.h to not redefine push, pop
---
 arm-asm.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 arm-tok.h |  5 +++++
 tcctok.h  |  2 +-
 3 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/arm-asm.c b/arm-asm.c
index aa37709..d79bf58 100644
--- a/arm-asm.c
+++ b/arm-asm.c
@@ -171,6 +171,61 @@ static void asm_nullary_opcode(int token)
     }
 }
 
+static void asm_block_data_transfer_opcode(TCCState *s1, int token)
+{
+    uint32_t opcode;
+    int op0_exclam;
+    Operand ops[2];
+    int nb_ops = 1;
+    parse_operand(s1, &ops[0]);
+    if (tok == '!') {
+        op0_exclam = 1;
+        next(); // skip '!'
+    }
+    if (tok == ',') {
+        next(); // skip comma
+        parse_operand(s1, &ops[1]);
+        ++nb_ops;
+    }
+    if (nb_ops < 1) {
+        expect("at least one operand");
+        return;
+    } else if (ops[nb_ops - 1].type != OP_REGSET32) {
+        expect("(last operand) register list");
+        return;
+    }
+
+    // block data transfer: 1 0 0 P U S W L << 20 (general case):
+    // operands:
+    //   Rn: bits 19...16 base register
+    //   Register List: bits 15...0
+
+    switch (ARM_INSTRUCTION_GROUP(token)) {
+    case TOK_ASM_pusheq: // TODO: Optimize 1-register case to: str ?, [sp, 
#-4]!
+        // Instruction: 1 I=0 P=1 U=0 S=0 W=1 L=0 << 20, op 1101
+        //   operands:
+        //      Rn: base register
+        //      Register List: bits 15...0
+        if (nb_ops != 1)
+            expect("exactly one operand");
+        else
+            asm_emit_opcode(token, (0x92d << 16) | ops[0].regset); // TODO: 
base register ?
+        break;
+    case TOK_ASM_popeq: // TODO: Optimize 1-register case to: ldr ?, [sp], #4
+        // Instruction: 1 I=0 P=0 U=1 S=0 W=0 L=1 << 20, op 1101
+        //   operands:
+        //      Rn: base register
+        //      Register List: bits 15...0
+        if (nb_ops != 1)
+            expect("exactly one operand");
+        else
+            asm_emit_opcode(token, (0x8bd << 16) | ops[0].regset); // TODO: 
base register ?
+        break;
+    default:
+        expect("block data transfer instruction");
+    }
+}
+
 ST_FUNC void asm_opcode(TCCState *s1, int token)
 {
     while (token == TOK_LINEFEED) {
@@ -185,6 +240,9 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
     }
 
     switch (ARM_INSTRUCTION_GROUP(token)) {
+    case TOK_ASM_pusheq:
+    case TOK_ASM_popeq:
+        return asm_block_data_transfer_opcode(s1, token);
     case TOK_ASM_nopeq:
     case TOK_ASM_wfeeq:
     case TOK_ASM_wfieq:
diff --git a/arm-tok.h b/arm-tok.h
index 6d9c596..82cb3dd 100644
--- a/arm-tok.h
+++ b/arm-tok.h
@@ -54,3 +54,8 @@
  DEF_ASM_CONDED(nop)
  DEF_ASM_CONDED(wfe)
  DEF_ASM_CONDED(wfi)
+
+ /* instruction macros */
+
+ DEF_ASM_CONDED(push)
+ DEF_ASM_CONDED(pop)
diff --git a/tcctok.h b/tcctok.h
index aeac1cd..4d2ce18 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -171,7 +171,7 @@
 
 /* pragma */
      DEF(TOK_pack, "pack")
-#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64)
+#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64) && 
!defined(TCC_TARGET_ARM)
      /* already defined for assembler */
      DEF(TOK_ASM_push, "push")
      DEF(TOK_ASM_pop, "pop")



reply via email to

[Prev in Thread] Current Thread [Next in Thread]