tinycc-devel
[Top][All Lists]
Advanced

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

[Tinycc-devel] [PATCH v2 1/8] arm-asm: Add cdp


From: Danny Milosavljevic
Subject: [Tinycc-devel] [PATCH v2 1/8] arm-asm: Add cdp
Date: Fri, 15 Jan 2021 17:26:39 +0100

Also add p0...p15 (coprocessors), c0...c15 (coprocessor register aliases)
---
 arm-asm.c                  | 77 ++++++++++++++++++++++++++++++++++++++
 arm-tok.h                  | 40 ++++++++++++++++++++
 tests/arm-asm-testsuite.sh |  1 +
 3 files changed, 118 insertions(+)

diff --git a/arm-asm.c b/arm-asm.c
index 285ec5e..b7f17e2 100644
--- a/arm-asm.c
+++ b/arm-asm.c
@@ -165,6 +165,26 @@ static void asm_emit_opcode(int token, uint32_t opcode) {
     gen_le32((condition_code_of_token(token) << 28) | opcode);
 }
 
+static void asm_emit_coprocessor_opcode(uint32_t high_nibble, uint8_t 
cp_number, uint8_t cp_opcode, uint8_t cp_destination_register, uint8_t 
cp_n_operand_register, uint8_t cp_m_operand_register, uint8_t cp_opcode2, int 
inter_processor_transfer)
+{
+    uint32_t opcode = 0xe000000;
+    if (inter_processor_transfer)
+        opcode |= 1 << 4;
+    //assert(cp_opcode < 16);
+    opcode |= cp_opcode << 20;
+    //assert(cp_n_operand_register < 16);
+    opcode |= cp_n_operand_register << 16;
+    //assert(cp_destination_register < 16);
+    opcode |= cp_destination_register << 12;
+    //assert(cp_number < 16);
+    opcode |= cp_number << 8;
+    //assert(cp_information < 8);
+    opcode |= cp_opcode2 << 5;
+    //assert(cp_m_operand_register < 16);
+    opcode |= cp_m_operand_register;
+    gen_le32((high_nibble << 28) | opcode);
+}
+
 static void asm_nullary_opcode(int token)
 {
     switch (ARM_INSTRUCTION_GROUP(token)) {
@@ -309,6 +329,60 @@ static void asm_binary_opcode(TCCState *s1, int token)
     }
 }
 
+static void asm_coprocessor_opcode(TCCState *s1, int token) {
+    uint8_t coprocessor;
+    Operand opcode1;
+    Operand opcode2;
+    uint8_t registers[3];
+    unsigned int i;
+
+    if (tok >= TOK_ASM_p0 && tok <= TOK_ASM_p15) {
+        coprocessor = tok - TOK_ASM_p0;
+        next();
+    } else {
+        expect("'p<number>'");
+        return;
+    }
+
+    if (tok == ',')
+        next();
+    else
+        expect("','");
+
+    parse_operand(s1, &opcode1);
+    if (opcode1.type != OP_IM8 || opcode1.e.v > 15) {
+        tcc_error("opcode1 of instruction '%s' must be an immediate value 
between 0 and 15", get_tok_str(token, NULL));
+        return;
+    }
+
+    for (i = 0; i < 3; ++i) {
+        if (tok == ',')
+            next();
+        else
+            expect("','");
+        if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) {
+            registers[i] = tok - TOK_ASM_c0;
+            next();
+        } else {
+            expect("'c<number>");
+            return;
+        }
+    }
+    if (tok == ',') {
+        next();
+        parse_operand(s1, &opcode2);
+    } else {
+        opcode2.type = OP_IM8;
+        opcode2.e.v = 0;
+    }
+    if (opcode2.type != OP_IM8 || opcode2.e.v > 15) {
+        tcc_error("opcode2 of instruction '%s' must be an immediate value 
between 0 and 15", get_tok_str(token, NULL));
+        return;
+    }
+
+    asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, 
opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0);
+}
+
 /* data processing and single data transfer instructions only */
 #define ENCODE_RN(register_index) ((register_index) << 16)
 #define ENCODE_RD(register_index) ((register_index) << 12)
@@ -1467,6 +1541,9 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
     case TOK_ASM_umlaleq:
     case TOK_ASM_umlalseq:
         return asm_long_multiplication_opcode(s1, token);
+
+    case TOK_ASM_cdpeq:
+        return asm_coprocessor_opcode(s1, token);
     default:
         expect("known instruction");
     }
diff --git a/arm-tok.h b/arm-tok.h
index f73add1..f6cad27 100644
--- a/arm-tok.h
+++ b/arm-tok.h
@@ -28,6 +28,44 @@
  DEF_ASM(lr) /* alias for r14 */
  DEF_ASM(pc) /* alias for r15 */
 
+ /* coprocessors */
+
+ DEF_ASM(p0)
+ DEF_ASM(p1)
+ DEF_ASM(p2)
+ DEF_ASM(p3)
+ DEF_ASM(p4)
+ DEF_ASM(p5)
+ DEF_ASM(p6)
+ DEF_ASM(p7)
+ DEF_ASM(p8)
+ DEF_ASM(p9)
+ DEF_ASM(p10)
+ DEF_ASM(p11)
+ DEF_ASM(p12)
+ DEF_ASM(p13)
+ DEF_ASM(p14)
+ DEF_ASM(p15)
+
+ /* coprocessor registers */
+
+ DEF_ASM(c0)
+ DEF_ASM(c1)
+ DEF_ASM(c2)
+ DEF_ASM(c3)
+ DEF_ASM(c4)
+ DEF_ASM(c5)
+ DEF_ASM(c6)
+ DEF_ASM(c7)
+ DEF_ASM(c8)
+ DEF_ASM(c9)
+ DEF_ASM(c10)
+ DEF_ASM(c11)
+ DEF_ASM(c12)
+ DEF_ASM(c13)
+ DEF_ASM(c14)
+ DEF_ASM(c15)
+
  /* data processing directives */
 
  DEF_ASM(asl)
@@ -170,3 +208,5 @@
  DEF_ASM_CONDED(rors)
  DEF_ASM_CONDED(rrx)
  DEF_ASM_CONDED(rrxs)
+
+ DEF_ASM_CONDED(cdp)
diff --git a/tests/arm-asm-testsuite.sh b/tests/arm-asm-testsuite.sh
index 0180628..f3c06c0 100755
--- a/tests/arm-asm-testsuite.sh
+++ b/tests/arm-asm-testsuite.sh
@@ -87,6 +87,7 @@ do
                    "r4, #0x0201" \
                    "r4, #0xFFFFFF00" \
                    "r2, #-4" \
+                   "p10, #7, c2, c0, c1, #4" \
                    "#4" \
                    "#-4" \
                    ""



reply via email to

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