CSKY: Add FPUV3 instructions, which supported by ck860f.
Co-Authored-By: Lifang Xia <lifang_xia@c-sky.com> gas/ * config/tc-csky.c (float_work_fpuv3_fmovi): New function, helper function to encode fpuv3 fmovi instructions. (float_work_fpuv3_fstore): New function. (struct literal): Add new member 'offset'. (csky_cpus): New cpu CK860f. (enter_literal): Return literal pool pointer instead of offset. (parse_rt): Adjust the change of enter_literal. (parse_rtf): Likewise. (v1_work_lrw): Likewise. (v1_work_jbsr): Likewise. (v2_work_lrw): Likewise. (v2_work_jbsr): Likewise. (v2_work_jsri): Likewise. (vdsp_work_vlrw): Likewise. (is_freglist_legal): Add handler for FPUV3. (parse_type_freg): Likewise. (is_imm_within_range): Set e.X_add_number if it is a signed and negtive number. (get_operand_value): Add handler for OPRND_TYPE_IMM9b, OPRND_TYPE_HFLOAT_FMOVI, OPRND_TYPE_SFLOAT_FMOVI and OPRND_TYPE_DFLOAT_FMOVI. (float_to_half): Convert float number to harf float. opcodes/ * csky-dis.c (csky_output_operand): Add handlers for OPRND_TYPE_HFLOAT_FMOVI, OPRND_TYPE_SFLOAT_FMOVI and OPRND_TYPE_DFLOAT_FMOVI. Refine OPRND_TYPE_FREGLIST_DASH to support FPUV3 instructions. * csky-opc.h (enum operand_type): New enum OPRND_TYPE_IMM9b, OPRND_TYPE_HFLOAT_FMOVI, OPRND_TYPE_SFLOAT_FMOVI and OPRND_TYPE_DFLOAT_FMOVI. (OPRND_MASK_4_5, OPRND_MASK_6, OPRND_MASK_6_7, OPRND_MASK_6_8, OPRND_MASK_7, OPRND_MASK_7_8, OPRND_MASK_17_24, OPRND_MASK_20, OPRND_MASK_20_21, OPRND_MASK_20_22, OPRND_MASK_20_23, OPRND_MASK_20_24, OPRND_MASK_20_25, OPRND_MASK_0_3or5_8, OPRND_MASK_0_3or6_7, OPRND_MASK_0_3or25, OPRND_MASK_0_4or21_24, OPRND_MASK_5or20_21, OPRND_MASK_5or20_22, OPRND_MASK_5or20_23, OPRND_MASK_5or20_24, OPRND_MASK_5or20_25, OPRND_MASK_8_9or21_25, OPRND_MASK_8_9or16_25, OPRND_MASK_4_6or20, OPRND_MASK_5_7or20, OPRND_MASK_4_5or20or25, OPRND_MASK_4_6or20or25, OPRND_MASK_4_7or20or25, OPRND_MASK_6_9or17_24, OPRND_MASK_6_7or20, OPRND_MASK_6or20, OPRND_MASK_7or20, OPRND_MASK_5or8_9or16_25, OPRND_MASK_5or8_9or20_25): Define. (csky_v2_opcodes): Add FPUV3 instructions. include/ * opcode/csky.h (CSKY_ISA_FLOAT_7E60): Define.
This commit is contained in:
parent
dfbee68088
commit
1feede9b38
7 changed files with 2356 additions and 33 deletions
|
@ -1,3 +1,31 @@
|
|||
2020-09-07 Cooper Qu <cooper.qu@linux.alibaba.com>
|
||||
|
||||
* config/tc-csky.c (float_work_fpuv3_fmovi): New function,
|
||||
helper function to encode fpuv3 fmovi instructions.
|
||||
(float_work_fpuv3_fstore): New function.
|
||||
(struct literal): Add new member 'offset'.
|
||||
(csky_cpus): New cpu CK860f.
|
||||
(enter_literal): Return literal pool pointer instead of offset.
|
||||
(parse_rt): Adjust the change of enter_literal.
|
||||
(parse_rtf): Likewise.
|
||||
(v1_work_lrw): Likewise.
|
||||
(v1_work_jbsr): Likewise.
|
||||
(v2_work_lrw): Likewise.
|
||||
(v2_work_jbsr): Likewise.
|
||||
(v2_work_jsri): Likewise.
|
||||
(vdsp_work_vlrw): Likewise.
|
||||
(is_freglist_legal): Add handler for FPUV3.
|
||||
(parse_type_freg): Likewise.
|
||||
(is_imm_within_range): Set e.X_add_number if it is a signed and
|
||||
negtive number.
|
||||
(get_operand_value): Add handler for OPRND_TYPE_IMM9b,
|
||||
OPRND_TYPE_HFLOAT_FMOVI, OPRND_TYPE_SFLOAT_FMOVI
|
||||
and OPRND_TYPE_DFLOAT_FMOVI.
|
||||
(float_to_half): Convert float number to harf float.
|
||||
* testsuite/gas/csky/case-fpuv3-ck860f/ : New folder containing
|
||||
the test cases for FPUV3, they are divided by instruction
|
||||
operands format and both have legal cases and illegal cases.
|
||||
|
||||
2020-09-08 Jozef Lawrynowicz <jozef.l@mittosystems.com>
|
||||
Kuan-Lin Chen <kuanlinchentw@gmail.com>
|
||||
|
||||
|
|
|
@ -172,6 +172,8 @@ bfd_boolean v2_work_movih (void);
|
|||
bfd_boolean v2_work_ori (void);
|
||||
bfd_boolean float_work_fmovi (void);
|
||||
bfd_boolean dsp_work_bloop (void);
|
||||
bfd_boolean float_work_fpuv3_fmovi (void);
|
||||
bfd_boolean float_work_fpuv3_fstore (void);
|
||||
|
||||
/* csky-opc.h must be included after workers are declared. */
|
||||
#include "opcodes/csky-opc.h"
|
||||
|
@ -295,6 +297,7 @@ struct csky_insn_info
|
|||
struct literal
|
||||
{
|
||||
unsigned short refcnt;
|
||||
unsigned int offset;
|
||||
unsigned char ispcrel;
|
||||
unsigned char unused;
|
||||
bfd_reloc_code_real_type r_type;
|
||||
|
@ -704,9 +707,10 @@ const struct csky_cpu_info csky_cpus[] =
|
|||
{"ck810ftv", CSKY_ARCH_810_BASE | CSKY_ARCH_FLOAT, CSKY_ISA_810 | CSKYV2_ISA_DSP | CSKY_ISA_VDSP | CSKY_ISA_FLOAT_810 | CSKY_ISA_TRUST},
|
||||
|
||||
/* CK860 Series. */
|
||||
#define CSKY_ISA_860 (CSKY_ISA_810 | CSKYV2_ISA_10E60)
|
||||
#define CSKY_ISA_FLOAT_860 (CSKY_ISA_FLOAT_810)
|
||||
#define CSKY_ISA_860 (CSKY_ISA_810 | CSKYV2_ISA_10E60 | CSKYV2_ISA_3E3R3)
|
||||
#define CSKY_ISA_860F (CSKY_ISA_860 | CSKY_ISA_FLOAT_7E60)
|
||||
{"ck860", CSKY_ARCH_860, CSKY_ISA_860},
|
||||
{"ck860f", CSKY_ARCH_860, CSKY_ISA_860F},
|
||||
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
|
@ -1718,7 +1722,7 @@ dump_literals (int isforce)
|
|||
poolsize = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct literal *
|
||||
enter_literal (expressionS *e,
|
||||
int ispcrel,
|
||||
unsigned char isdouble,
|
||||
|
@ -1772,7 +1776,7 @@ enter_literal (expressionS *e,
|
|||
p->e.X_add_number * sizeof (LITTLENUM_TYPE)) == 0)))
|
||||
{
|
||||
p->refcnt ++;
|
||||
return i;
|
||||
return p;
|
||||
}
|
||||
if (p->e.X_op == O_big)
|
||||
{
|
||||
|
@ -1787,6 +1791,7 @@ enter_literal (expressionS *e,
|
|||
p->e = *e;
|
||||
p->r_type = insn_reloc;
|
||||
p->isdouble = isdouble;
|
||||
p->offset = i;
|
||||
if (isdouble)
|
||||
p->dbnum = dbnum;
|
||||
if (e->X_op == O_big)
|
||||
|
@ -1806,7 +1811,7 @@ enter_literal (expressionS *e,
|
|||
} else
|
||||
poolsize += (p->isdouble ? 2 : 1);
|
||||
|
||||
return i;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Check whether we must dump the literal pool here.
|
||||
|
@ -2056,7 +2061,6 @@ parse_rt (char *s,
|
|||
long reg ATTRIBUTE_UNUSED)
|
||||
{
|
||||
expressionS e;
|
||||
int n;
|
||||
|
||||
if (ep)
|
||||
/* Indicate nothing there. */
|
||||
|
@ -2089,24 +2093,45 @@ parse_rt (char *s,
|
|||
/* If the instruction has work, literal handling is in the work. */
|
||||
if (!csky_insn.opcode->work)
|
||||
{
|
||||
n = enter_literal (&e, ispcrel, 0, 0);
|
||||
struct literal *p = enter_literal (&e, ispcrel, 0, 0);
|
||||
if (ep)
|
||||
*ep = e;
|
||||
|
||||
/* Create a reference to pool entry. */
|
||||
ep->X_op = O_symbol;
|
||||
ep->X_add_symbol = poolsym;
|
||||
ep->X_add_number = n << 2;
|
||||
ep->X_add_number = p->offset << 2;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static int float_to_half (void *f, void *h)
|
||||
{
|
||||
int imm_e;
|
||||
int imm_f;
|
||||
unsigned int value_f = *(unsigned int *)f;
|
||||
unsigned short value_h;
|
||||
|
||||
imm_e = ((value_f >> 23) & 0xff);
|
||||
imm_f = ((value_f & 0x7fffff));
|
||||
|
||||
imm_e = ((imm_e - 127 + 15) << 10);
|
||||
imm_f = ((imm_f & 0x7fe000) >> 13);
|
||||
|
||||
value_h = (value_f & 0x80000000 ? 0x8000 : 0x0) | imm_e | imm_f;
|
||||
|
||||
if (h)
|
||||
*(unsigned short *)h = value_h;
|
||||
|
||||
return value_h;
|
||||
}
|
||||
|
||||
static char *
|
||||
parse_rtf (char *s, int ispcrel, expressionS *ep)
|
||||
{
|
||||
expressionS e;
|
||||
int n = 0;
|
||||
struct literal *p = NULL;
|
||||
|
||||
if (ep)
|
||||
/* Indicate nothing there. */
|
||||
|
@ -2127,15 +2152,24 @@ parse_rtf (char *s, int ispcrel, expressionS *ep)
|
|||
else
|
||||
{
|
||||
uint64_t dbnum;
|
||||
if (strstr (csky_insn.opcode->mnemonic, "flrws"))
|
||||
if (strstr(csky_insn.opcode->mnemonic, "flrws")
|
||||
|| strstr(csky_insn.opcode->mnemonic, "flrw.32"))
|
||||
{
|
||||
s = parse_fexp (s, &e, 0, &dbnum);
|
||||
n = enter_literal (&e, ispcrel, 0, dbnum);
|
||||
p = enter_literal (& e, ispcrel, 0, dbnum);
|
||||
}
|
||||
else if (strstr (csky_insn.opcode->mnemonic, "flrwd"))
|
||||
else if (strstr(csky_insn.opcode->mnemonic, "flrwd")
|
||||
|| strstr(csky_insn.opcode->mnemonic, "flrw.64"))
|
||||
{
|
||||
s = parse_fexp (s, &e, 1, &dbnum);
|
||||
n = enter_literal (&e, ispcrel, 1, dbnum);
|
||||
p = enter_literal (& e, ispcrel, 1, dbnum);
|
||||
}
|
||||
else if (strstr(csky_insn.opcode->mnemonic, "flrwh")
|
||||
|| strstr(csky_insn.opcode->mnemonic, "flrw.16"))
|
||||
{
|
||||
s = parse_fexp (s, &e, 0, NULL);
|
||||
e.X_add_number = float_to_half (&e.X_add_number, &e.X_add_number);
|
||||
p = enter_literal (& e, ispcrel, 0, 0);
|
||||
}
|
||||
else
|
||||
as_bad (_("unrecognized opcode"));
|
||||
|
@ -2146,7 +2180,7 @@ parse_rtf (char *s, int ispcrel, expressionS *ep)
|
|||
/* Create a reference to pool entry. */
|
||||
ep->X_op = O_symbol;
|
||||
ep->X_add_symbol = poolsym;
|
||||
ep->X_add_number = n << 2;
|
||||
ep->X_add_number = p->offset << 2;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -2592,6 +2626,7 @@ is_freglist_legal (char **oper)
|
|||
int reg1 = -1;
|
||||
int reg2 = -1;
|
||||
int len = 0;
|
||||
int shift = 0;
|
||||
reg1 = csky_get_freg_val (*oper, &len);
|
||||
*oper += len;
|
||||
|
||||
|
@ -2627,12 +2662,34 @@ is_freglist_legal (char **oper)
|
|||
}
|
||||
|
||||
reg2 = reg2 - reg1;
|
||||
if (reg2 > (int)0x3)
|
||||
/* The fldm/fstm in CSKY_ISA_FLOAT_7E60 has 5 bits frz(reg1). */
|
||||
shift = 4;
|
||||
if (strncmp (csky_insn.opcode->mnemonic, "fstm", 4) == 0
|
||||
|| strncmp (csky_insn.opcode->mnemonic, "fldm", 4) == 0)
|
||||
{
|
||||
SET_ERROR_STRING(ERROR_REG_FORMAT, (void *)"vry-vrx is over range");
|
||||
return FALSE;
|
||||
if ((!(isa_flag & CSKY_ISA_FLOAT_7E60)
|
||||
&& (reg2 > (int)15 || reg1 > 15))
|
||||
|| ((isa_flag & CSKY_ISA_FLOAT_7E60)
|
||||
&& (reg2 > (int)31 || reg1 > (int)31)))
|
||||
{
|
||||
/* ISA_FLOAT_E1 fstm/fldm fry-frx is within 15.
|
||||
ISA_FLOAT_7E60 fstm(u)/fldm(u) frx-fry is within 31. */
|
||||
SET_ERROR_STRING(ERROR_REG_FORMAT, (void *)"frx-fry is over range");
|
||||
return FALSE;
|
||||
}
|
||||
if ((mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_860)
|
||||
{
|
||||
shift = 5;
|
||||
}
|
||||
}
|
||||
reg2 <<= 4;
|
||||
else
|
||||
{
|
||||
if (reg2 > (int)0x3) {
|
||||
SET_ERROR_STRING(ERROR_REG_FORMAT, (void *)"vry-vrx is over range");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
reg2 <<= shift;
|
||||
reg1 |= reg2;
|
||||
csky_insn.val[csky_insn.idx++] = reg1;
|
||||
return TRUE;
|
||||
|
@ -2788,6 +2845,8 @@ is_imm_within_range (char **oper, int min, int max)
|
|||
ret = FALSE;
|
||||
SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
|
||||
}
|
||||
if (!e.X_unsigned)
|
||||
e.X_add_number |= 0x80000000;
|
||||
csky_insn.val[csky_insn.idx++] = e.X_add_number;
|
||||
}
|
||||
|
||||
|
@ -2990,7 +3049,8 @@ parse_type_freg (char** oper, int even)
|
|||
}
|
||||
|
||||
if (IS_CSKY_V2 (mach_flag)
|
||||
&& (csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2)
|
||||
&& ((csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2)
|
||||
|| !(csky_insn.opcode->isa_flag32 & CSKY_ISA_FLOAT_7E60))
|
||||
&& reg > 15)
|
||||
{
|
||||
if ((csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2))
|
||||
|
@ -3537,6 +3597,8 @@ get_operand_value (struct csky_opcode_info *op,
|
|||
return is_imm_within_range (oper, 0, 127);
|
||||
case OPRND_TYPE_IMM8b:
|
||||
return is_imm_within_range (oper, 0, 255);
|
||||
case OPRND_TYPE_IMM9b:
|
||||
return is_imm_within_range (oper, -256, 255);
|
||||
case OPRND_TYPE_IMM12b:
|
||||
return is_imm_within_range (oper, 0, 4095);
|
||||
case OPRND_TYPE_IMM15b:
|
||||
|
@ -3720,7 +3782,37 @@ get_operand_value (struct csky_opcode_info *op,
|
|||
| ((dbnum & 0x8000000000000000ULL) >> 43));
|
||||
return TRUE;
|
||||
}
|
||||
case OPRND_TYPE_HFLOAT_FMOVI:
|
||||
case OPRND_TYPE_SFLOAT_FMOVI:
|
||||
case OPRND_TYPE_DFLOAT_FMOVI:
|
||||
/* For fpuv3 fmovis and fmovid, which accept a constant
|
||||
float with a limited range. */
|
||||
{
|
||||
uint64_t dbnum;
|
||||
int imm4, imm8, sign;
|
||||
|
||||
*oper = parse_fexp (*oper, &csky_insn.e1, 1, &dbnum);
|
||||
if (csky_insn.e1.X_op == O_absent)
|
||||
return FALSE;
|
||||
|
||||
/* Convert the representation from IEEE double to the 13-bit
|
||||
encoding used internally for fmovis and fmovid. */
|
||||
imm4 = 11 - (((dbnum & 0x7ff0000000000000ULL) >> 52) - 1023);
|
||||
/* Check float range. */
|
||||
if ((dbnum & 0x00000fffffffffffULL) || imm4 < 0 || imm4 > 15)
|
||||
{
|
||||
csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
imm8 = (dbnum & 0x000ff00000000000ULL) >> 44;
|
||||
sign = (dbnum & 0x8000000000000000ULL) >> 58;
|
||||
csky_insn.e1.X_add_number
|
||||
= (((imm8 & 0x3) << 8)
|
||||
| ((imm8 & 0xfc) << 18)
|
||||
| ((imm4 & 0xf) << 16)
|
||||
| sign);
|
||||
return TRUE;
|
||||
}
|
||||
/* For grs v2. */
|
||||
case OPRND_TYPE_IMM_OFF18b:
|
||||
*oper = parse_exp (*oper, &csky_insn.e1);
|
||||
|
@ -5999,12 +6091,12 @@ v1_work_lrw (void)
|
|||
csky_insn.inst |= reg << 8;
|
||||
if (output_literal)
|
||||
{
|
||||
int n = enter_literal (&csky_insn.e1, 0, 0, 0);
|
||||
struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
|
||||
|
||||
/* Create a reference to pool entry. */
|
||||
csky_insn.e1.X_op = O_symbol;
|
||||
csky_insn.e1.X_add_symbol = poolsym;
|
||||
csky_insn.e1.X_add_number = n << 2;
|
||||
csky_insn.e1.X_add_number = p->offset << 2;
|
||||
}
|
||||
|
||||
if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
|
||||
|
@ -6212,12 +6304,12 @@ v1_work_jbsr (void)
|
|||
csky_insn.opcode_idx = 0;
|
||||
csky_insn.isize = 2;
|
||||
|
||||
int n = enter_literal (&csky_insn.e1, 1, 0, 0);
|
||||
struct literal *p = enter_literal (&csky_insn.e1, 1, 0, 0);
|
||||
|
||||
/* Create a reference to pool entry. */
|
||||
csky_insn.e1.X_op = O_symbol;
|
||||
csky_insn.e1.X_add_symbol = poolsym;
|
||||
csky_insn.e1.X_add_number = n << 2;
|
||||
csky_insn.e1.X_add_number = p->offset << 2;
|
||||
|
||||
/* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
|
||||
fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
|
||||
|
@ -6226,7 +6318,7 @@ v1_work_jbsr (void)
|
|||
if (csky_insn.e1.X_op != O_absent && do_jsri2bsr)
|
||||
/* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
|
||||
fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
|
||||
2, & (litpool + (csky_insn.e1.X_add_number >> 2))->e,
|
||||
2, &p->e,
|
||||
1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2);
|
||||
}
|
||||
csky_generate_insn ();
|
||||
|
@ -6815,11 +6907,11 @@ v2_work_lrw (void)
|
|||
|
||||
if (output_literal)
|
||||
{
|
||||
int n = enter_literal (&csky_insn.e1, 0, 0, 0);
|
||||
struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
|
||||
/* Create a reference to pool entry. */
|
||||
csky_insn.e1.X_op = O_symbol;
|
||||
csky_insn.e1.X_add_symbol = poolsym;
|
||||
csky_insn.e1.X_add_number = n << 2;
|
||||
csky_insn.e1.X_add_number = p->offset << 2;
|
||||
}
|
||||
/* If 16bit force. */
|
||||
if (csky_insn.flag_force == INSN_OPCODE16F)
|
||||
|
@ -6960,11 +7052,11 @@ v2_work_jbsr (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
int n = enter_literal (&csky_insn.e1, 0, 0, 0);
|
||||
struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
|
||||
csky_insn.output = frag_more (4);
|
||||
csky_insn.e1.X_op = O_symbol;
|
||||
csky_insn.e1.X_add_symbol = poolsym;
|
||||
csky_insn.e1.X_add_number = n << 2;
|
||||
csky_insn.e1.X_add_number = p->offset << 2;
|
||||
fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
|
||||
4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
|
||||
if (do_jsri2bsr || IS_CSKY_ARCH_810 (mach_flag))
|
||||
|
@ -6994,10 +7086,10 @@ bfd_boolean
|
|||
v2_work_jsri (void)
|
||||
{
|
||||
/* dump literal. */
|
||||
int n = enter_literal (&csky_insn.e1, 1, 0, 0);
|
||||
struct literal *p = enter_literal (&csky_insn.e1, 1, 0, 0);
|
||||
csky_insn.e1.X_op = O_symbol;
|
||||
csky_insn.e1.X_add_symbol = poolsym;
|
||||
csky_insn.e1.X_add_number = n << 2;
|
||||
csky_insn.e1.X_add_number = p->offset << 2;
|
||||
|
||||
/* Generate relax or reloc if necessary. */
|
||||
csky_generate_frags ();
|
||||
|
@ -7012,7 +7104,7 @@ v2_work_jsri (void)
|
|||
For 'jbsr .L1', this reloc type's symbol
|
||||
is bound to '.L1', isn't bound to literal pool. */
|
||||
fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
|
||||
4, &(litpool + (csky_insn.e1.X_add_number >> 2))->e, 1,
|
||||
4, &p->e, 1,
|
||||
BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2);
|
||||
csky_insn.output = frag_more (4);
|
||||
dwarf2_emit_insn (0);
|
||||
|
@ -7155,6 +7247,57 @@ float_work_fmovi (void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Like float_work_fmovi, but for FPUV3 fmovi.16, fmovi.32 and fmovi.64
|
||||
instructions. */
|
||||
|
||||
bfd_boolean
|
||||
float_work_fpuv3_fmovi (void)
|
||||
{
|
||||
int rx = csky_insn.val[0];
|
||||
int idx = csky_insn.opcode_idx;
|
||||
int imm4 = 0;
|
||||
int imm8 = 0;
|
||||
int sign = 0;
|
||||
|
||||
csky_insn.inst = csky_insn.opcode->op32[idx].opcode | rx;
|
||||
|
||||
if (csky_insn.opcode->op32[idx].operand_num == 3)
|
||||
{
|
||||
/* fmovi.xx frz, imm9, imm4. */
|
||||
imm8 = csky_insn.val[1];
|
||||
imm4 = csky_insn.val[2];
|
||||
if (imm8 < 0 || (imm8 & 0x80000000))
|
||||
{
|
||||
sign = (1 << 5);
|
||||
imm8 = 0 - imm8;
|
||||
}
|
||||
|
||||
if (imm8 > 255)
|
||||
{
|
||||
csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* imm8 store at bit [25:20] and [9:8]. */
|
||||
/* imm4 store at bit [19:16]. */
|
||||
/* sign store at bit [5]. */
|
||||
csky_insn.inst = csky_insn.inst
|
||||
| ((imm8 & 0x3) << 8)
|
||||
| ((imm8 & 0xfc) << 18)
|
||||
| ((imm4 & 0xf) << 16)
|
||||
| sign;
|
||||
}
|
||||
else
|
||||
{
|
||||
csky_insn.inst |= (uint32_t) csky_insn.e1.X_add_number;
|
||||
}
|
||||
|
||||
csky_insn.output = frag_more(4);
|
||||
csky_insn.isize = 4;
|
||||
csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bfd_boolean
|
||||
dsp_work_bloop (void)
|
||||
{
|
||||
|
@ -7196,6 +7339,21 @@ dsp_work_bloop (void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
bfd_boolean
|
||||
float_work_fpuv3_fstore(void)
|
||||
{
|
||||
/* Generate relax or reloc if necessary. */
|
||||
csky_generate_frags ();
|
||||
/* Generate the insn by mask. */
|
||||
csky_generate_insn ();
|
||||
/* Write inst to frag. */
|
||||
csky_write_insn (csky_insn.output,
|
||||
csky_insn.inst,
|
||||
csky_insn.isize);
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* The following are for assembler directive handling. */
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2020-09-07 Cooper Qu <cooper.qu@linux.alibaba.com>
|
||||
|
||||
* opcode/csky.h (CSKY_ISA_FLOAT_7E60): Define.
|
||||
|
||||
2020-09-08 Jozef Lawrynowicz <jozef.l@mittosystems.com>
|
||||
Kuan-Lin Chen <kuanlinchentw@gmail.com>
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@
|
|||
#define CSKY_ISA_FLOAT_1E3 (1L << 27)
|
||||
/* 807 support (803f & 807f). */
|
||||
#define CSKY_ISA_FLOAT_3E4 (1L << 28)
|
||||
/* 860 support. */
|
||||
#define CSKY_ISA_FLOAT_7E60 (1L << 36)
|
||||
/* Vector DSP support. */
|
||||
#define CSKY_ISA_VDSP (1L << 29)
|
||||
#define CSKY_ISA_VDSP_2 (1L << 30)
|
||||
|
|
|
@ -1,3 +1,27 @@
|
|||
2020-09-07 Cooper Qu <cooper.qu@linux.alibaba.com>
|
||||
|
||||
* csky-dis.c (csky_output_operand): Add handlers for
|
||||
OPRND_TYPE_HFLOAT_FMOVI, OPRND_TYPE_SFLOAT_FMOVI and
|
||||
OPRND_TYPE_DFLOAT_FMOVI. Refine OPRND_TYPE_FREGLIST_DASH
|
||||
to support FPUV3 instructions.
|
||||
* csky-opc.h (enum operand_type): New enum OPRND_TYPE_IMM9b,
|
||||
OPRND_TYPE_HFLOAT_FMOVI, OPRND_TYPE_SFLOAT_FMOVI and
|
||||
OPRND_TYPE_DFLOAT_FMOVI.
|
||||
(OPRND_MASK_4_5, OPRND_MASK_6, OPRND_MASK_6_7, OPRND_MASK_6_8,
|
||||
OPRND_MASK_7, OPRND_MASK_7_8, OPRND_MASK_17_24,
|
||||
OPRND_MASK_20, OPRND_MASK_20_21, OPRND_MASK_20_22,
|
||||
OPRND_MASK_20_23, OPRND_MASK_20_24, OPRND_MASK_20_25,
|
||||
OPRND_MASK_0_3or5_8, OPRND_MASK_0_3or6_7, OPRND_MASK_0_3or25,
|
||||
OPRND_MASK_0_4or21_24, OPRND_MASK_5or20_21,
|
||||
OPRND_MASK_5or20_22, OPRND_MASK_5or20_23, OPRND_MASK_5or20_24,
|
||||
OPRND_MASK_5or20_25, OPRND_MASK_8_9or21_25,
|
||||
OPRND_MASK_8_9or16_25, OPRND_MASK_4_6or20, OPRND_MASK_5_7or20,
|
||||
OPRND_MASK_4_5or20or25, OPRND_MASK_4_6or20or25,
|
||||
OPRND_MASK_4_7or20or25, OPRND_MASK_6_9or17_24,
|
||||
OPRND_MASK_6_7or20, OPRND_MASK_6or20, OPRND_MASK_7or20,
|
||||
OPRND_MASK_5or8_9or16_25, OPRND_MASK_5or8_9or20_25): Define.
|
||||
(csky_v2_opcodes): Add FPUV3 instructions.
|
||||
|
||||
2020-09-08 Alex Coplan <alex.coplan@arm.com>
|
||||
|
||||
* aarch64-dis.c (print_operands): Pass CPU features to
|
||||
|
|
|
@ -621,6 +621,62 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
|||
|
||||
sprintf (buf, "%f", fvalue);
|
||||
strcat (str, buf);
|
||||
break;
|
||||
}
|
||||
case OPRND_TYPE_HFLOAT_FMOVI:
|
||||
case OPRND_TYPE_SFLOAT_FMOVI:
|
||||
{
|
||||
int imm4;
|
||||
int imm8;
|
||||
imm4 = ((inst >> 16) & 0xf);
|
||||
imm4 = (138 - imm4) << 23;
|
||||
|
||||
imm8 = ((inst >> 8) & 0x3);
|
||||
imm8 |= (((inst >> 20) & 0x3f) << 2);
|
||||
imm8 <<= 15;
|
||||
|
||||
value = ((inst >> 5) & 1) << 31;
|
||||
value |= imm4 | imm8;
|
||||
|
||||
imm4 = 138 - (imm4 >> 23);
|
||||
imm8 >>= 15;
|
||||
if ((inst >> 5) & 1)
|
||||
{
|
||||
imm8 = 0 - imm8;
|
||||
}
|
||||
|
||||
float f = 0;
|
||||
memcpy (&f, &value, sizeof (float));
|
||||
sprintf (str, "%s%f\t// imm9:%4d, imm4:%2d", str, f, imm8, imm4);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OPRND_TYPE_DFLOAT_FMOVI:
|
||||
{
|
||||
uint64_t imm4;
|
||||
uint64_t imm8;
|
||||
uint64_t dvalue;
|
||||
imm4 = ((inst >> 16) & 0xf);
|
||||
imm4 = (1034 - imm4) << 52;
|
||||
|
||||
imm8 = ((inst >> 8) & 0x3);
|
||||
imm8 |= (((inst >> 20) & 0x3f) << 2);
|
||||
imm8 <<= 44;
|
||||
|
||||
dvalue = (((uint64_t)inst >> 5) & 1) << 63;
|
||||
dvalue |= imm4 | imm8;
|
||||
|
||||
imm4 = 1034 - (imm4 >> 52);
|
||||
imm8 >>= 44;
|
||||
if (inst >> 5)
|
||||
{
|
||||
imm8 = 0 - imm8;
|
||||
}
|
||||
double d = 0;
|
||||
memcpy (&d, &dvalue, sizeof (double));
|
||||
sprintf (str, "%s%lf\t// imm9:%4ld, imm4:%2ld", str, d, imm8, imm4);
|
||||
|
||||
break;
|
||||
}
|
||||
case OPRND_TYPE_LABEL_WITH_BRACKET:
|
||||
|
@ -653,8 +709,20 @@ csky_output_operand (char *str, struct operand const *oprnd,
|
|||
case OPRND_TYPE_FREGLIST_DASH:
|
||||
if (IS_CSKY_V2 (mach_flag))
|
||||
{
|
||||
int vrx = value & 0xf;
|
||||
int vry = vrx + (value >> 4);
|
||||
int vrx = 0;
|
||||
int vry = 0;
|
||||
if (dis_info.isa & CSKY_ISA_FLOAT_7E60
|
||||
&& (strstr (str, "fstm") != NULL
|
||||
|| strstr (str, "fldm") != NULL))
|
||||
{
|
||||
vrx = value & 0x1f;
|
||||
vry = vrx + (value >> 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
vrx = value & 0xf;
|
||||
vry = vrx + (value >> 4);
|
||||
}
|
||||
sprintf (buf, "fr%d-fr%d", vrx, vry);
|
||||
strcat (str, buf);
|
||||
}
|
||||
|
|
2039
opcodes/csky-opc.h
2039
opcodes/csky-opc.h
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue