arm-asm: Add vldr, vstr
Also add s0...s31, d0...d15
This commit is contained in:
parent
31dde11ad5
commit
cdbb55396c
3 changed files with 169 additions and 1 deletions
97
arm-asm.c
97
arm-asm.c
|
@ -1444,6 +1444,97 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(TCC_ARM_VFP)
|
||||
#define CP_SINGLE_PRECISION_FLOAT 10
|
||||
#define CP_DOUBLE_PRECISION_FLOAT 11
|
||||
|
||||
/* Read the VFP register referred to by T.
|
||||
If OK, returns its number.
|
||||
If not OK, returns -1. */
|
||||
static int asm_parse_vfp_regvar(int t, int double_precision)
|
||||
{
|
||||
if (double_precision) {
|
||||
if (t >= TOK_ASM_d0 && t <= TOK_ASM_d15)
|
||||
return t - TOK_ASM_d0;
|
||||
} else {
|
||||
if (t >= TOK_ASM_s0 && t <= TOK_ASM_s31)
|
||||
return t - TOK_ASM_s0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int token)
|
||||
{
|
||||
Operand ops[3];
|
||||
uint8_t coprocessor = 0;
|
||||
uint8_t coprocessor_destination_register = 0;
|
||||
int long_transfer = 0;
|
||||
int reg;
|
||||
// Note: vldr p1, c0, [r4, #4] ; simple offset: r0 = *(int*)(r4+4); r4 unchanged
|
||||
// Note: Not allowed: vldr p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4
|
||||
// Note: Not allowed: vldr p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4
|
||||
|
||||
if ((reg = asm_parse_vfp_regvar(tok, 0)) != -1) {
|
||||
coprocessor = CP_SINGLE_PRECISION_FLOAT;
|
||||
coprocessor_destination_register = reg;
|
||||
long_transfer = coprocessor_destination_register & 1;
|
||||
coprocessor_destination_register >>= 1;
|
||||
next();
|
||||
} else if ((reg = asm_parse_vfp_regvar(tok, 1)) != -1) {
|
||||
coprocessor = CP_DOUBLE_PRECISION_FLOAT;
|
||||
coprocessor_destination_register = reg;
|
||||
next();
|
||||
} else {
|
||||
expect("floating point register");
|
||||
return;
|
||||
}
|
||||
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
|
||||
if (tok != '[')
|
||||
expect("'['");
|
||||
else
|
||||
next(); // skip '['
|
||||
|
||||
parse_operand(s1, &ops[1]);
|
||||
if (ops[1].type != OP_REG32) {
|
||||
expect("(first source operand) register");
|
||||
return;
|
||||
}
|
||||
if (tok == ',') {
|
||||
next(); // skip ','
|
||||
parse_operand(s1, &ops[2]);
|
||||
if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) {
|
||||
expect("immediate offset");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// end of input expression in brackets--assume 0 offset
|
||||
ops[2].type = OP_IM8;
|
||||
ops[2].e.v = 0;
|
||||
}
|
||||
if (tok != ']')
|
||||
expect("']'");
|
||||
else
|
||||
next(); // skip ']'
|
||||
|
||||
switch (ARM_INSTRUCTION_GROUP(token)) {
|
||||
case TOK_ASM_vldreq:
|
||||
asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 1);
|
||||
break;
|
||||
case TOK_ASM_vstreq:
|
||||
asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 0);
|
||||
break;
|
||||
default:
|
||||
expect("floating point data transfer instruction");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token)
|
||||
{
|
||||
Operand ops[3];
|
||||
|
@ -1785,6 +1876,12 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
|
|||
case TOK_ASM_stcleq:
|
||||
return asm_coprocessor_data_transfer_opcode(s1, token);
|
||||
|
||||
#if defined(TCC_ARM_VFP)
|
||||
case TOK_ASM_vldreq:
|
||||
case TOK_ASM_vstreq:
|
||||
return asm_floating_point_single_data_transfer_opcode(s1, token);
|
||||
#endif
|
||||
|
||||
default:
|
||||
expect("known instruction");
|
||||
}
|
||||
|
|
59
arm-tok.h
59
arm-tok.h
|
@ -66,6 +66,60 @@
|
|||
DEF_ASM(c14)
|
||||
DEF_ASM(c15)
|
||||
|
||||
/* single-precision VFP registers */
|
||||
|
||||
DEF_ASM(s0)
|
||||
DEF_ASM(s1)
|
||||
DEF_ASM(s2)
|
||||
DEF_ASM(s3)
|
||||
DEF_ASM(s4)
|
||||
DEF_ASM(s5)
|
||||
DEF_ASM(s6)
|
||||
DEF_ASM(s7)
|
||||
DEF_ASM(s8)
|
||||
DEF_ASM(s9)
|
||||
DEF_ASM(s10)
|
||||
DEF_ASM(s11)
|
||||
DEF_ASM(s12)
|
||||
DEF_ASM(s13)
|
||||
DEF_ASM(s14)
|
||||
DEF_ASM(s15)
|
||||
DEF_ASM(s16)
|
||||
DEF_ASM(s17)
|
||||
DEF_ASM(s18)
|
||||
DEF_ASM(s19)
|
||||
DEF_ASM(s20)
|
||||
DEF_ASM(s21)
|
||||
DEF_ASM(s22)
|
||||
DEF_ASM(s23)
|
||||
DEF_ASM(s24)
|
||||
DEF_ASM(s25)
|
||||
DEF_ASM(s26)
|
||||
DEF_ASM(s27)
|
||||
DEF_ASM(s28)
|
||||
DEF_ASM(s29)
|
||||
DEF_ASM(s30)
|
||||
DEF_ASM(s31)
|
||||
|
||||
/* double-precision VFP registers */
|
||||
|
||||
DEF_ASM(d0)
|
||||
DEF_ASM(d1)
|
||||
DEF_ASM(d2)
|
||||
DEF_ASM(d3)
|
||||
DEF_ASM(d4)
|
||||
DEF_ASM(d5)
|
||||
DEF_ASM(d6)
|
||||
DEF_ASM(d7)
|
||||
DEF_ASM(d8)
|
||||
DEF_ASM(d9)
|
||||
DEF_ASM(d10)
|
||||
DEF_ASM(d11)
|
||||
DEF_ASM(d12)
|
||||
DEF_ASM(d13)
|
||||
DEF_ASM(d14)
|
||||
DEF_ASM(d15)
|
||||
|
||||
/* data processing directives */
|
||||
|
||||
DEF_ASM(asl)
|
||||
|
@ -225,3 +279,8 @@
|
|||
DEF_ASM_CONDED(cdp)
|
||||
DEF_ASM_CONDED(mcr)
|
||||
DEF_ASM_CONDED(mrc)
|
||||
|
||||
// Floating point high-level instructions
|
||||
|
||||
DEF_ASM_CONDED(vldr)
|
||||
DEF_ASM_CONDED(vstr)
|
||||
|
|
|
@ -5,8 +5,14 @@ set -e
|
|||
# Note: "{r3}" is definitely different--but would complicate the assembler.
|
||||
|
||||
state="`mktemp -d`"
|
||||
cat ../arm-tok.h |grep DEF_ASM |grep -v 'not useful' |grep -v '#define' |grep -v '/[*]' |sed -e 's;^[ ]*DEF_ASM[^(]*(\(.*\)).*$;\1;' | egrep -v '^((r|c|p)[0-9]+|fp|ip|sp|lr|pc|asl)$' | while read s
|
||||
cat ../arm-tok.h |grep DEF_ASM |grep -v 'not useful' |grep -v '#define' |grep -v '/[*]' |sed -e 's;^[ ]*DEF_ASM[^(]*(\(.*\)).*$;\1;' | egrep -v '^((r|c|p|s|d)[0-9]+|fp|ip|sp|lr|pc|asl)$' | while read s
|
||||
do
|
||||
# If VFP is disabled, skip VFP tests.
|
||||
if [ "${s#v}" != "${s}" ] && ! grep -q "CONFIG_arm_vfp=yes" ../config.mak
|
||||
then
|
||||
echo "note: skipping VFP instruction: $s (because VFP is disabled)">&2
|
||||
continue
|
||||
fi
|
||||
ok=0
|
||||
for args in "r3, r4, r5, r6" \
|
||||
"r3, r4, r5" \
|
||||
|
@ -103,6 +109,12 @@ do
|
|||
"p5, c2, [r3, #-4]" \
|
||||
"p5, c2, [r3, #0x45]" \
|
||||
"p5, c2, [r3, #-0x45]" \
|
||||
"s2, [r3]" \
|
||||
"s3, [r4]" \
|
||||
"s2, [r3, #4]" \
|
||||
"s2, [r3, #-4]" \
|
||||
"s2, [r3, #0x45]" \
|
||||
"s2, [r3, #-0x45]" \
|
||||
""
|
||||
do
|
||||
#echo ".syntax unified" > a.s
|
||||
|
|
Loading…
Reference in a new issue