[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 */
- [Tinycc-devel] [PATCH 0/9] Improve ARM inline assembler, Danny Milosavljevic, 2020/12/27
- [Tinycc-devel] [PATCH 4/9] arm-asm: Warn if regset registers are not specified in ascending order, Danny Milosavljevic, 2020/12/27
- [Tinycc-devel] [PATCH 2/9] arm-asm: For data processing instructions, support shifts and rotations.,
Danny Milosavljevic <=
- [Tinycc-devel] [PATCH 3/9] arm-asm: Support rotation for sxtb, sxth, uxtb, uxth, Danny Milosavljevic, 2020/12/27
- [Tinycc-devel] [PATCH 7/9] arm-asm: Print a warning if asm_binary_opcode is used with SP as operand, Danny Milosavljevic, 2020/12/27
- [Tinycc-devel] [PATCH 1/9] arm-asm: Add lsl, lsr, asr, ror, rrx, Danny Milosavljevic, 2020/12/27
- [Tinycc-devel] [PATCH 5/9] arm-asm: Add error case in asm_multiplication_opcode, Danny Milosavljevic, 2020/12/27
- [Tinycc-devel] [PATCH 9/9] arm-asm: Raise error if asm_data_processing_opcode and asm_shift_opcode try to use PC for register-controlled shifts, Danny Milosavljevic, 2020/12/27
- [Tinycc-devel] [PATCH 6/9] arm-asm: Raise an error if asm_binary_opcode is used with PC as operand, Danny Milosavljevic, 2020/12/27
- [Tinycc-devel] [PATCH 8/9] arm-asm: Raise error if more than two operands are specified on mov, mvn, cmp, cmn, tst, teq, Danny Milosavljevic, 2020/12/27
- Re: [Tinycc-devel] [PATCH 0/9] Improve ARM inline assembler, Danny Milosavljevic, 2020/12/27