tinycc-devel
[Top][All Lists]
Advanced

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

[Tinycc-devel] [PATCH 2/9] arm-asm: For data processing instructions, su


From: Danny Milosavljevic
Subject: [Tinycc-devel] [PATCH 2/9] arm-asm: For data processing instructions, support shifts and rotations.
Date: Mon, 28 Dec 2020 02:44:06 +0100

---
 arm-asm.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++--------
 arm-tok.h |  4 ++++
 2 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/arm-asm.c b/arm-asm.c
index 6dc24c0..ef75091 100644
--- a/arm-asm.c
+++ b/arm-asm.c
@@ -413,18 +413,55 @@ static void asm_data_processing_opcode(TCCState *s1, int 
token)
 {
     Operand ops[3];
     int nb_ops;
+    Operand shift = {};
+    int nb_shift = 0;
+    uint32_t operands = 0;
 
     /* 16 entries per instruction for the different condition codes */
     uint32_t opcode_idx = (ARM_INSTRUCTION_GROUP(token) - TOK_ASM_andeq) >> 4;
 
-    for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
+    for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) {
+        if (tok == TOK_ASM_asl || tok == TOK_ASM_lsl || tok == TOK_ASM_lsr || 
tok == TOK_ASM_asr || tok == TOK_ASM_ror || tok == TOK_ASM_rrx)
+            break;
         parse_operand(s1, &ops[nb_ops]);
-        if (tok != ',') {
-            ++nb_ops;
+        ++nb_ops;
+        if (tok != ',')
             break;
-        }
         next(); // skip ','
     }
+    if (tok == ',')
+        next();
+    switch (tok) {
+    case TOK_ASM_asl:
+    case TOK_ASM_lsl:
+    case TOK_ASM_asr:
+    case TOK_ASM_lsr:
+    case TOK_ASM_ror:
+        switch (tok) {
+        case TOK_ASM_asl:
+            /* fallthrough */
+        case TOK_ASM_lsl:
+            operands |= ENCODE_BARREL_SHIFTER_MODE_LSL;
+            break;
+        case TOK_ASM_asr:
+            operands |= ENCODE_BARREL_SHIFTER_MODE_ASR;
+            break;
+        case TOK_ASM_lsr:
+            operands |= ENCODE_BARREL_SHIFTER_MODE_LSR;
+            break;
+        case TOK_ASM_ror:
+            operands |= ENCODE_BARREL_SHIFTER_MODE_ROR;
+            break;
+        }
+        next();
+        parse_operand(s1, &shift);
+        nb_shift = 1;
+        break;
+    case TOK_ASM_rrx:
+        next();
+        operands |= ENCODE_BARREL_SHIFTER_MODE_ROR;
+        break;
+    }
     if (nb_ops < 2)
         expect("at least two operands");
     else if (nb_ops == 2) {
@@ -437,7 +474,6 @@ static void asm_data_processing_opcode(TCCState *s1, int 
token)
         return;
     } else {
         uint32_t opcode = 0;
-        uint32_t operands = 0;
 
         // data processing (general case):
         // operands:
@@ -461,16 +497,13 @@ static void asm_data_processing_opcode(TCCState *s1, int 
token)
             operands |= ENCODE_RN(ops[1].reg);
         switch (ops[2].type) {
         case OP_REG32:
-            // TODO: Parse and encode shift.
             operands |= ops[2].reg;
             break;
         case OP_IM8:
-            // TODO: Parse and encode rotation.
             operands |= ENCODE_IMMEDIATE_FLAG;
             operands |= ops[2].e.v;
             break;
         case OP_IM8N: // immediate negative value
-            // TODO: Parse and encode rotation.
             operands |= ENCODE_IMMEDIATE_FLAG;
             /* Instruction swapping:
                0001 = EOR - Rd:= Op1 EOR Op2     -> difficult
@@ -534,6 +567,13 @@ static void asm_data_processing_opcode(TCCState *s1, int 
token)
             expect("(second source operand) register or immediate value");
         }
 
+        if (nb_shift) {
+            if (operands & ENCODE_IMMEDIATE_FLAG)
+                tcc_error("immediate rotation not implemented");
+            else
+                operands |= asm_encode_shift(&shift);
+        }
+
         /* S=0 and S=1 entries alternate one after another, in that order */
         opcode |= (opcode_idx & 1) ? ENCODE_SET_CONDITION_CODES : 0;
         asm_emit_opcode(token, opcode | operands);
diff --git a/arm-tok.h b/arm-tok.h
index a1fb158..6d2483b 100644
--- a/arm-tok.h
+++ b/arm-tok.h
@@ -28,6 +28,10 @@
  DEF_ASM(lr) /* alias for r14 */
  DEF_ASM(pc) /* alias for r15 */
 
+ /* data processing directives */
+
+ DEF_ASM(asl)
+
 #define ARM_INSTRUCTION_GROUP(tok) ((((tok) - TOK_ASM_nopeq) & 0xFFFFFFF0) + 
TOK_ASM_nopeq)
 
 /* Note: condition code is 4 bits */



reply via email to

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