History

arm-asm: Add vmov

Danny Milosavljevic committed 5 years ago

Commit 04165941 parent b82e52a3 files · +129 −6Browse files

Unified · Split

3 files
  1. arm-asm.c +124 −6
  2. arm-tok.h +1 −0
  3. tests/arm-asm-testsuite.sh +4 −0
arm-asm.c+124−6
@@ -1648,18 +1648,115 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int toke · 1647 unmodified lines
16481648 asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, first_regset_register, &ops[0], &offset, 0, preincrement, op0_exclam, extra_register_bit, load);
16491649 }
16501650
1651+#define VMOV_FRACTIONAL_DIGITS 7
1652+#define VMOV_ONE 10000000 /* pow(10, VMOV_FRACTIONAL_DIGITS) */
1653+
1654+static uint32_t vmov_parse_fractional_part(const char* s)
1655+{
1656+ uint32_t result = 0;
1657+ int i;
1658+ for (i = 0; i < VMOV_FRACTIONAL_DIGITS; ++i) {
1659+ char c = *s;
1660+ result *= 10;
1661+ if (c >= '0' && c <= '9') {
1662+ result += (c - '0');
1663+ ++s;
1664+ }
1665+ }
1666+ if (*s)
1667+ expect("decimal numeral");
1668+ return result;
1669+}
1670+
1671+static int vmov_linear_approx_index(uint32_t beginning, uint32_t end, uint32_t value)
1672+{
1673+ int i;
1674+ uint32_t k;
1675+ uint32_t xvalue;
1676+
1677+ k = (end - beginning)/16;
1678+ for (xvalue = beginning, i = 0; i < 16; ++i, xvalue += k) {
1679+ if (value == xvalue)
1680+ return i;
1681+ }
1682+ //assert(0);
1683+ return -1;
1684+}
1685+
1686+static uint32_t vmov_parse_immediate_value() {
1687+ uint32_t value;
1688+ unsigned long integral_value;
1689+ const char *p;
1690+
1691+ if (tok != TOK_PPNUM) {
1692+ expect("immediate value");
1693+ return 0;
1694+ }
1695+ p = tokc.str.data;
1696+ errno = 0;
1697+ integral_value = strtoul(p, (char **)&p, 0);
1698+
1699+ if (errno || integral_value >= 32) {
1700+ tcc_error("invalid floating-point immediate value");
1701+ return 0;
1702+ }
1703+
1704+ value = (uint32_t) integral_value * VMOV_ONE;
1705+ if (*p == '.') {
1706+ ++p;
1707+ value += vmov_parse_fractional_part(p);
1708+ }
1709+ next();
1710+ return value;
1711+}
1712+
1713+static uint8_t vmov_encode_immediate_value(uint32_t value)
1714+{
1715+ uint32_t limit;
1716+ uint32_t end = 0;
1717+ uint32_t beginning = 0;
1718+ int r = -1;
1719+ int n;
1720+ int i;
1721+
1722+ limit = 32 * VMOV_ONE;
1723+ for (i = 0; i < 8; ++i) {
1724+ if (value < limit) {
1725+ end = limit;
1726+ limit >>= 1;
1727+ beginning = limit;
1728+ r = i;
1729+ } else
1730+ limit >>= 1;
1731+ }
1732+ if (r == -1 || value < beginning || value > end) {
1733+ tcc_error("invalid decimal number for vmov: %d", value);
1734+ return 0;
1735+ }
1736+ n = vmov_linear_approx_index(beginning, end, value);
1737+ return n | (((3 - r) & 0x7) << 4);
1738+}
1739+
16511740 // Not standalone.
16521741 static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s1, int token, uint8_t coprocessor, uint8_t CRd) {
16531742 uint8_t opcode1 = 0;
16541743 uint8_t opcode2 = 0;
16551744 uint8_t operands[3] = {0, 0, 0};
1656− Operand operand;
1745+ uint32_t immediate_value = 0;
1746+ int op_minus = 0;
1747+ uint8_t code;
16571748
16581749 operands[0] = CRd;
16591750
1660− parse_operand(s1, &operand);
1661− if (operand.type != OP_IM8 && operand.type != OP_IM8N) {
1662− expect("Immediate value");
1751+ if (tok == '#' || tok == '$') {
1752+ next();
1753+ if (tok == '-') {
1754+ op_minus = 1;
1755+ next();
1756+ }
1757+ immediate_value = vmov_parse_immediate_value();
1758+ } else {
1759+ expect("'#'");
16631760 return;
16641761 }
16651762
@@ -1669,7 +1766,7 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 3 unmodified lines
16691766 case TOK_ASM_vcmpeq_f64:
16701767 opcode2 = 2;
16711768 operands[1] = 5;
1672− if (operand.e.v) {
1769+ if (immediate_value) {
16731770 expect("Immediate value 0");
16741771 return;
16751772 }
@@ -1678,11 +1775,22 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 2 unmodified lines
16781775 case TOK_ASM_vcmpeeq_f64:
16791776 opcode2 = 6;
16801777 operands[1] = 5;
1681− if (operand.e.v) {
1778+ if (immediate_value) {
16821779 expect("Immediate value 0");
16831780 return;
16841781 }
16851782 break;
1783+ case TOK_ASM_vmoveq_f32:
1784+ case TOK_ASM_vmoveq_f64:
1785+ opcode2 = 0;
1786+ if (op_minus)
1787+ operands[1] = 0x8;
1788+ else
1789+ operands[1] = 0x0;
1790+ code = vmov_encode_immediate_value(immediate_value);
1791+ operands[1] |= code >> 4;
1792+ operands[2] = code & 0xF;
1793+ break;
16861794 default:
16871795 expect("known floating point with immediate instruction");
16881796 return;
@@ -1749,6 +1857,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 60 unmodified lines
17491857 case TOK_ASM_vsqrteq_f64:
17501858 case TOK_ASM_vcmpeq_f64:
17511859 case TOK_ASM_vcmpeeq_f64:
1860+ case TOK_ASM_vmoveq_f64:
17521861 coprocessor = CP_DOUBLE_PRECISION_FLOAT;
17531862 }
17541863
@@ -1881,6 +1990,13 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 126 unmodified lines
18811990 operands[1] = 4;
18821991 operand_1_register = 0;
18831992 break;
1993+ case TOK_ASM_vmoveq_f32:
1994+ case TOK_ASM_vmoveq_f64:
1995+ opcode1 = 11; // "Other" instruction
1996+ opcode2 = 2;
1997+ operands[1] = 0;
1998+ operand_1_register = 0;
1999+ break;
18842000 // TODO: vcvt; vcvtr
18852001 default:
18862002 expect("known floating point instruction");
@@ -2284,6 +2400,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 397 unmodified lines
22842400 case TOK_ASM_vsqrteq_f32:
22852401 case TOK_ASM_vcmpeq_f32:
22862402 case TOK_ASM_vcmpeeq_f32:
2403+ case TOK_ASM_vmoveq_f32:
22872404 case TOK_ASM_vmlaeq_f64:
22882405 case TOK_ASM_vmlseq_f64:
22892406 case TOK_ASM_vnmlseq_f64:
@@ -2298,6 +2415,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 8 unmodified lines
22982415 case TOK_ASM_vsqrteq_f64:
22992416 case TOK_ASM_vcmpeq_f64:
23002417 case TOK_ASM_vcmpeeq_f64:
2418+ case TOK_ASM_vmoveq_f64:
23012419 asm_floating_point_data_processing_opcode(s1, token);
23022420 return;
23032421
arm-tok.h+1−0
@@ -323,6 +323,7 @@ · 322 unmodified lines
323323 DEF_ASM_CONDED_VFP_F32_F64(vsqrt)
324324 DEF_ASM_CONDED_VFP_F32_F64(vcmp)
325325 DEF_ASM_CONDED_VFP_F32_F64(vcmpe)
326+ DEF_ASM_CONDED_VFP_F32_F64(vmov)
326327
327328 DEF_ASM_CONDED(vpush)
328329 DEF_ASM_CONDED(vpop)
tests/arm-asm-testsuite.sh+4−0
@@ -147,6 +147,10 @@ do · 146 unmodified lines
147147 "d2, d3" \
148148 "s2, #0" \
149149 "d2, #0" \
150+ "s3, #0.0" \
151+ "d3, #0.0" \
152+ "s4, #-0.1796875" \
153+ "d4, #0.1796875" \
150154 ""
151155 do
152156 #echo ".syntax unified" > a.s

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t