[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Tinycc-devel] [PATCH 1/8] arm-asm: Add cdp
From: |
Danny Milosavljevic |
Subject: |
[Tinycc-devel] [PATCH 1/8] arm-asm: Add cdp |
Date: |
Thu, 14 Jan 2021 23:22:20 +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" \
""
- [Tinycc-devel] [PATCH 0/8] Implement ARM VFP in ARM inline assembler, Danny Milosavljevic, 2021/01/14
- [Tinycc-devel] [PATCH 4/8] arm-asm: Add ldc, ldcl, stc, stcl, Danny Milosavljevic, 2021/01/14
- [Tinycc-devel] [PATCH 1/8] arm-asm: Add cdp,
Danny Milosavljevic <=
- [Tinycc-devel] [PATCH 3/8] arm-asm: Add mcr, mrc, Danny Milosavljevic, 2021/01/14
- [Tinycc-devel] [PATCH 5/8] arm-asm: Add ldc2, ldc2l, stc2, stc2l, Danny Milosavljevic, 2021/01/14
- [Tinycc-devel] [PATCH 8/8] arm-asm: Add vneg, vabs, vsqrt, vcmp, vcmpe, Danny Milosavljevic, 2021/01/14
- [Tinycc-devel] [PATCH 2/8] arm-asm: Add cdp2, Danny Milosavljevic, 2021/01/14
- [Tinycc-devel] [PATCH 7/8] arm-asm: Add vmla, vmls, vnmls, vnmla, vmul, vnmul, vadd, vsub, vdiv, Danny Milosavljevic, 2021/01/14
- [Tinycc-devel] [PATCH 6/8] arm-asm: Add vldr, vstr., Danny Milosavljevic, 2021/01/14