CSKY: Refine literals pool dump process and float register parser.

gas/
	* config/tc-csky.c (struct literal): New member bignum.
	(dump_literals): Handle big constant.
	(enter_literal): Likewise.
	(parse_type_freg): Handle vector register.
This commit is contained in:
Cooper Qu 2020-09-02 14:04:52 +08:00 committed by Lifang Xia
parent 7d0a7dce39
commit e61ef79e3a
2 changed files with 58 additions and 3 deletions

View File

@ -1,3 +1,10 @@
2020-09-02 Cooper Qu <cooper.qu@linux.alibaba.com>
* config/tc-csky.c (struct literal): New member bignum.
(dump_literals): Handle big constant.
(enter_literal): Likewise.
(parse_type_freg): Handle vector register.
2020-09-01 H.J. Lu <hongjiu.lu@intel.com>
* doc/as.texi: Document the .tls_common directive.

View File

@ -302,6 +302,7 @@ struct literal
struct tls_addend tls_addend;
unsigned char isdouble;
uint64_t dbnum;
LITTLENUM_TYPE bignum[SIZE_OF_LARGE_NUMBER + 6];
};
static void csky_idly (void);
@ -1660,7 +1661,7 @@ dump_literals (int isforce)
colon (S_GET_NAME (poolsym));
for (i = 0, p = litpool; i < poolsize; i += (p->isdouble ? 2 : 1), p++)
for (i = 0, p = litpool; i < poolsize; p++)
{
insn_reloc = p->r_type;
if (insn_reloc == BFD_RELOC_CKCORE_TLS_IE32
@ -1684,8 +1685,18 @@ dump_literals (int isforce)
emit_expr (& p->e, 4);
}
}
else if (p->e.X_op == O_big)
{
memcpy (generic_bignum, p->bignum, sizeof (p->bignum));
emit_expr (& p->e, p->e.X_add_number * CHARS_PER_LITTLENUM);
}
else
emit_expr (& p->e, 4);
if (p->e.X_op == O_big)
i += ((p->e.X_add_number * CHARS_PER_LITTLENUM) >> 2);
else
i += (p->isdouble ? 2 : 1);
}
if (isforce && IS_CSKY_ARCH_V2 (mach_flag))
@ -1739,7 +1750,7 @@ enter_literal (expressionS *e,
}
/* Search pool for value so we don't have duplicates. */
for (p = litpool, i = 0; i < poolsize; i += (p->isdouble ? 2 : 1), p++)
for (p = litpool,i = 0; i < poolsize; p++)
{
if (e->X_op == p->e.X_op
&& e->X_add_symbol == p->e.X_add_symbol
@ -1751,11 +1762,21 @@ enter_literal (expressionS *e,
&& insn_reloc != BFD_RELOC_CKCORE_TLS_LDM32
&& insn_reloc != BFD_RELOC_CKCORE_TLS_LDO32
&& insn_reloc != BFD_RELOC_CKCORE_TLS_IE32
&& insn_reloc != BFD_RELOC_CKCORE_TLS_LE32)
&& insn_reloc != BFD_RELOC_CKCORE_TLS_LE32
&& (e->X_op != O_big
|| (memcmp (generic_bignum, p->bignum,
p->e.X_add_number * sizeof (LITTLENUM_TYPE)) == 0)))
{
p->refcnt ++;
return i;
}
if (p->e.X_op == O_big)
{
i += (p->e.X_add_number >> 1);
i += (p->e.X_add_number & 0x1);
}
else
i += (p->isdouble ? 2 : 1);
}
p->refcnt = 1;
p->ispcrel = ispcrel;
@ -1764,6 +1785,8 @@ enter_literal (expressionS *e,
p->isdouble = isdouble;
if (isdouble)
p->dbnum = dbnum;
if (e->X_op == O_big)
memcpy (p->bignum, generic_bignum, sizeof (p->bignum));
if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
|| insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
@ -1773,7 +1796,12 @@ enter_literal (expressionS *e,
p->tls_addend.offset = csky_insn.output - frag_now->fr_literal;
literal_insn_offset = p;
}
if (p->e.X_op == O_big) {
poolsize += (p->e.X_add_number >> 1);
poolsize += (p->e.X_add_number & 0x1);
} else
poolsize += (p->isdouble ? 2 : 1);
return i;
}
@ -2956,6 +2984,26 @@ parse_type_freg (char** oper, int even)
SET_ERROR_STRING (ERROR_EXP_EVEN_FREG, NULL);
return FALSE;
}
if (IS_CSKY_V2 (mach_flag)
&& (csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2)
&& reg > 15)
{
if ((csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2))
{
SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE, reg);
}
else
{
SET_ERROR_INTEGER (ERROR_FREG_OVER_RANGE, reg);
}
return FALSE;
}
/* TODO: recognize vreg or freg. */
if (reg > 31)
{
SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE, reg);
}
csky_insn.val[csky_insn.idx++] = reg;
return TRUE;
}