mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-24 03:40:09 +08:00
arm-asm: Add vcvt
This commit is contained in:
parent
f1fb23a661
commit
24c94fff09
141
arm-asm.c
141
arm-asm.c
@ -1902,6 +1902,127 @@ static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *s1, in
|
||||
}
|
||||
}
|
||||
|
||||
static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int token) {
|
||||
uint8_t coprocessor = 0;
|
||||
Operand ops[3];
|
||||
uint8_t opcode1 = 11;
|
||||
uint8_t opcode2 = 2;
|
||||
|
||||
switch (ARM_INSTRUCTION_GROUP(token)) {
|
||||
case TOK_ASM_vcvtreq_s32_f64:
|
||||
case TOK_ASM_vcvtreq_u32_f64:
|
||||
case TOK_ASM_vcvteq_s32_f64:
|
||||
case TOK_ASM_vcvteq_u32_f64:
|
||||
case TOK_ASM_vcvteq_f64_s32:
|
||||
case TOK_ASM_vcvteq_f64_u32:
|
||||
case TOK_ASM_vcvteq_f32_f64:
|
||||
coprocessor = CP_DOUBLE_PRECISION_FLOAT;
|
||||
break;
|
||||
case TOK_ASM_vcvtreq_s32_f32:
|
||||
case TOK_ASM_vcvtreq_u32_f32:
|
||||
case TOK_ASM_vcvteq_s32_f32:
|
||||
case TOK_ASM_vcvteq_u32_f32:
|
||||
case TOK_ASM_vcvteq_f32_s32:
|
||||
case TOK_ASM_vcvteq_f32_u32:
|
||||
case TOK_ASM_vcvteq_f64_f32:
|
||||
coprocessor = CP_SINGLE_PRECISION_FLOAT;
|
||||
break;
|
||||
default:
|
||||
tcc_error("Unknown coprocessor for instruction '%s'", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
parse_operand(s1, &ops[0]);
|
||||
ops[1].type = OP_IM8;
|
||||
ops[1].e.v = 8;
|
||||
/* floating-point -> integer */
|
||||
switch (ARM_INSTRUCTION_GROUP(token)) {
|
||||
case TOK_ASM_vcvtreq_s32_f32:
|
||||
case TOK_ASM_vcvtreq_s32_f64:
|
||||
case TOK_ASM_vcvteq_s32_f32:
|
||||
case TOK_ASM_vcvteq_s32_f64:
|
||||
ops[1].e.v |= 1; // signed
|
||||
/* fall through */
|
||||
case TOK_ASM_vcvteq_u32_f32:
|
||||
case TOK_ASM_vcvteq_u32_f64:
|
||||
case TOK_ASM_vcvtreq_u32_f32:
|
||||
case TOK_ASM_vcvtreq_u32_f64:
|
||||
ops[1].e.v |= 4; // to_integer (opc2)
|
||||
break;
|
||||
/* floating-point size conversion */
|
||||
case TOK_ASM_vcvteq_f64_f32:
|
||||
case TOK_ASM_vcvteq_f32_f64:
|
||||
ops[1].e.v = 7;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[2]);
|
||||
|
||||
switch (ARM_INSTRUCTION_GROUP(token)) {
|
||||
/* floating-point -> integer */
|
||||
case TOK_ASM_vcvteq_s32_f32:
|
||||
case TOK_ASM_vcvteq_s32_f64:
|
||||
case TOK_ASM_vcvteq_u32_f32:
|
||||
case TOK_ASM_vcvteq_u32_f64:
|
||||
opcode2 |= 4; // round_zero
|
||||
break;
|
||||
|
||||
/* integer -> floating-point */
|
||||
case TOK_ASM_vcvteq_f64_s32:
|
||||
case TOK_ASM_vcvteq_f32_s32:
|
||||
opcode2 |= 4; // signed--special
|
||||
break;
|
||||
|
||||
/* floating-point size conversion */
|
||||
case TOK_ASM_vcvteq_f64_f32:
|
||||
case TOK_ASM_vcvteq_f32_f64:
|
||||
opcode2 |= 4; // always set
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ARM_INSTRUCTION_GROUP(token)) {
|
||||
case TOK_ASM_vcvteq_f64_u32:
|
||||
case TOK_ASM_vcvteq_f64_s32:
|
||||
case TOK_ASM_vcvteq_f64_f32:
|
||||
if (ops[0].type == OP_VREG64 && ops[2].type == OP_VREG32) {
|
||||
} else {
|
||||
expect("d<number>, s<number>");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (coprocessor == CP_SINGLE_PRECISION_FLOAT) {
|
||||
if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG32) {
|
||||
} else {
|
||||
expect("s<number>, s<number>");
|
||||
return;
|
||||
}
|
||||
} else if (coprocessor == CP_DOUBLE_PRECISION_FLOAT) {
|
||||
if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG64) {
|
||||
} else {
|
||||
expect("s<number>, d<number>");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ops[2].type == OP_VREG32) {
|
||||
if (ops[2].reg & 1)
|
||||
opcode2 |= 1;
|
||||
ops[2].reg >>= 1;
|
||||
}
|
||||
if (ops[0].type == OP_VREG32) {
|
||||
if (ops[0].reg & 1)
|
||||
opcode1 |= 4;
|
||||
ops[0].reg >>= 1;
|
||||
}
|
||||
asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, (ops[2].type == OP_IM8) ? ops[2].e.v : ops[2].reg, opcode2, 0);
|
||||
}
|
||||
|
||||
static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) {
|
||||
uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT;
|
||||
uint8_t opcode1 = 0;
|
||||
@ -1920,8 +2041,6 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) {
|
||||
VFMA 1?10 ?0? Must be unconditional
|
||||
VFMS 1?10 ?1? Must be unconditional
|
||||
|
||||
VCVT*
|
||||
|
||||
VMOV Fd, Fm
|
||||
VMOV Sn, Sm, Rd, Rn
|
||||
VMOV Rd, Rn, Sn, Sm
|
||||
@ -2092,7 +2211,6 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) {
|
||||
ops[1].e.v = 0;
|
||||
}
|
||||
break;
|
||||
// TODO: vcvt; vcvtr
|
||||
default:
|
||||
expect("known floating point instruction");
|
||||
return;
|
||||
@ -2580,6 +2698,23 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
|
||||
asm_floating_point_data_processing_opcode(s1, token);
|
||||
return;
|
||||
|
||||
case TOK_ASM_vcvtreq_s32_f32:
|
||||
case TOK_ASM_vcvtreq_s32_f64:
|
||||
case TOK_ASM_vcvteq_s32_f32:
|
||||
case TOK_ASM_vcvteq_s32_f64:
|
||||
case TOK_ASM_vcvtreq_u32_f32:
|
||||
case TOK_ASM_vcvtreq_u32_f64:
|
||||
case TOK_ASM_vcvteq_u32_f32:
|
||||
case TOK_ASM_vcvteq_u32_f64:
|
||||
case TOK_ASM_vcvteq_f64_s32:
|
||||
case TOK_ASM_vcvteq_f32_s32:
|
||||
case TOK_ASM_vcvteq_f64_u32:
|
||||
case TOK_ASM_vcvteq_f32_u32:
|
||||
case TOK_ASM_vcvteq_f64_f32:
|
||||
case TOK_ASM_vcvteq_f32_f64:
|
||||
asm_floating_point_vcvt_data_processing_opcode(s1, token);
|
||||
return;
|
||||
|
||||
case TOK_ASM_vpusheq:
|
||||
case TOK_ASM_vpopeq:
|
||||
case TOK_ASM_vldmeq:
|
||||
|
36
arm-tok.h
36
arm-tok.h
@ -186,6 +186,24 @@
|
||||
DEF_ASM_CONDED_WITH_SUFFIX(x, f32) \
|
||||
DEF_ASM_CONDED_WITH_SUFFIX(x, f64)
|
||||
|
||||
#define DEF_ASM_CONDED_WITH_TWO_SUFFIXES(x, y, z) \
|
||||
DEF(TOK_ASM_ ## x ## eq ## _ ## y ## _ ## z, #x "eq." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## ne ## _ ## y ## _ ## z, #x "ne." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## cs ## _ ## y ## _ ## z, #x "cs." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## cc ## _ ## y ## _ ## z, #x "cc." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## mi ## _ ## y ## _ ## z, #x "mi." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## pl ## _ ## y ## _ ## z, #x "pl." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## vs ## _ ## y ## _ ## z, #x "vs." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## vc ## _ ## y ## _ ## z, #x "vc." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## hi ## _ ## y ## _ ## z, #x "hi." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## ls ## _ ## y ## _ ## z, #x "ls." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## ge ## _ ## y ## _ ## z, #x "ge." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## lt ## _ ## y ## _ ## z, #x "lt." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## gt ## _ ## y ## _ ## z, #x "gt." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## le ## _ ## y ## _ ## z, #x "le." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## _ ## y ## _ ## z, #x "." #y "." #z) \
|
||||
DEF(TOK_ASM_ ## x ## rsvd ## _ ## y ## _ ## z, #x "rsvd." #y "." #z)
|
||||
|
||||
/* Note: add new tokens after nop (MUST always use DEF_ASM_CONDED) */
|
||||
|
||||
DEF_ASM_CONDED(nop)
|
||||
@ -335,6 +353,24 @@
|
||||
DEF_ASM_CONDED_VFP_F32_F64(vcmpe)
|
||||
DEF_ASM_CONDED_VFP_F32_F64(vmov)
|
||||
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, s32, f64)
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, s32, f32)
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, u32, f64)
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, u32, f32)
|
||||
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, s32, f64)
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, s32, f32)
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, u32, f64)
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, u32, f32)
|
||||
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f64, s32)
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f32, s32)
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f64, u32)
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f32, u32)
|
||||
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f64, f32)
|
||||
DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f32, f64)
|
||||
|
||||
DEF_ASM_CONDED(vpush)
|
||||
DEF_ASM_CONDED(vpop)
|
||||
DEF_ASM_CONDED(vldm)
|
||||
|
@ -13,7 +13,7 @@ cat ../arm-tok.h | \
|
||||
grep -v 'DEF_ASM_CONDED_WITH_SUFFIX(x' | \
|
||||
sed -e 's;^[ ]*DEF_ASM_CONDED_VFP_F32_F64[^(]*(\(.*\)).*$; DEF_ASM_CONDED(\1.f32)\
|
||||
DEF_ASM_CONDED(\1.f64);g' | \
|
||||
sed -e 's;^[ ]*DEF_ASM[^(]*(\(.*\)).*$;\1;g' | \
|
||||
sed -e 's;^[ ]*DEF_ASM[^(]*(\(.*\)).*$;\1;g' -e 's;, ;.;g' | \
|
||||
egrep -v '^((r|c|p|s|d)[0-9]+|fp|ip|sp|lr|pc|asl|apsr_nzcv|fpsid|fpscr|fpexc)$' | while read s
|
||||
do
|
||||
as_opts=""
|
||||
@ -162,6 +162,8 @@ do
|
||||
"fpexc, r2" \
|
||||
"fpscr, r2" \
|
||||
"fpsid, r2" \
|
||||
"s3, d4" \
|
||||
"d4, s3" \
|
||||
""
|
||||
do
|
||||
#echo ".syntax unified" > a.s
|
||||
|
Loading…
Reference in New Issue
Block a user