--- arm-asm.c | 68 ++++++++++++++++++++++++++++++++++---- arm-tok.h | 5 +++ tests/arm-asm-testsuite.sh | 2 ++ 3 files changed, 68 insertions(+), 7 deletions(-)
diff --git a/arm-asm.c b/arm-asm.c index 539fc31..f3598d2 100644 --- a/arm-asm.c +++ b/arm-asm.c @@ -1539,6 +1539,8 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { uint8_t registers[3]; uint8_t nb_registers = 0; int has_register_1 = 1; + Operand operand; + int operand_is_zero = 0; int reg; /* TODO: @@ -1551,12 +1553,6 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { VFMS 1?10 ?1? Must be unconditional VMOV Fd, const 1?11 ?0? Needs fixed-point arithmetic - VABS Nope Completely different encoding - VSQRT Nope Completely different encoding - - VCMP{E} - >VCMP with 0 - VCVT* VMOV Fd, Fm @@ -1587,7 +1583,24 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { */ for (nb_registers = 0; nb_registers < 3; ) { - if (coprocessor == CP_SINGLE_PRECISION_FLOAT) { + if (nb_registers == 1 && tok == '#') { + switch (ARM_INSTRUCTION_GROUP(token)) { + case TOK_ASM_vcmpeq: + case TOK_ASM_vcmpeeq: + registers[1] = 0; + parse_operand(s1, &operand); + if (operand.type != OP_IM8) { + expect("Immediate value"); + return; + } + if (operand.e.v) { + expect("Immediate value 0"); + return; + } + operand_is_zero = 1; + break; + } + } else if (coprocessor == CP_SINGLE_PRECISION_FLOAT) { if ((reg = asm_parse_vfp_regvar(tok, 0)) != -1) { registers[nb_registers] = reg; next(); @@ -1619,6 +1632,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { else break; } + if (nb_registers == 2) { // implicit registers[2] = registers[1]; registers[1] = registers[0]; @@ -1666,6 +1680,41 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { opcode1 = 8; opcode2 = 0; break; + case TOK_ASM_vnegeq: + opcode1 = 11; // Other" instruction + opcode2 = 2; + registers[1] = 1; + has_register_1 = 0; + break; + case TOK_ASM_vabseq: + opcode1 = 11; // "Other" instruction + opcode2 = 6; + registers[1] = 0; + has_register_1 = 0; + break; + case TOK_ASM_vsqrteq: + opcode1 = 11; // "Other" instruction + opcode2 = 6; + registers[1] = 1; + has_register_1 = 0; + break; + case TOK_ASM_vcmpeq: + opcode1 = 11; // "Other" instruction + opcode2 = 2; + registers[1] = 4; + if (operand_is_zero) + registers[1] |= 1; + has_register_1 = 0; + break; + case TOK_ASM_vcmpeeq: + opcode1 = 11; // "Other" instruction + opcode2 = 6; + registers[1] = 4; + if (operand_is_zero) + registers[1] |= 1; + has_register_1 = 0; + break; + // TODO: vcvt; vcvtr default: expect("known floating point instruction"); return; @@ -2046,6 +2095,11 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) case TOK_ASM_vaddeq: case TOK_ASM_vsubeq: case TOK_ASM_vdiveq: + case TOK_ASM_vnegeq: + case TOK_ASM_vabseq: + case TOK_ASM_vsqrteq: + case TOK_ASM_vcmpeq: + case TOK_ASM_vcmpeeq: return asm_floating_point_data_processing_opcode(s1, token); #endif diff --git a/arm-tok.h b/arm-tok.h index 6adbc68..eb4b294 100644 --- a/arm-tok.h +++ b/arm-tok.h @@ -294,3 +294,8 @@ DEF_ASM_CONDED(vadd) DEF_ASM_CONDED(vsub) DEF_ASM_CONDED(vdiv) + DEF_ASM_CONDED(vneg) + DEF_ASM_CONDED(vabs) + DEF_ASM_CONDED(vsqrt) + DEF_ASM_CONDED(vcmp) + DEF_ASM_CONDED(vcmpe) diff --git a/tests/arm-asm-testsuite.sh b/tests/arm-asm-testsuite.sh index 28675a8..2c06de8 100755 --- a/tests/arm-asm-testsuite.sh +++ b/tests/arm-asm-testsuite.sh @@ -111,6 +111,8 @@ do "s2, s3" \ "d2, d3, d4" \ "d2, d3" \ + "s2, #0" \ + "d2, #0" \ "" do #echo ".syntax unified" > a.s _______________________________________________ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel