mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-03-07 13:39:43 +08:00
RISC-V/gas: allow generating up to 176-bit instructions with .insn
For the time being simply utilize O_big to avoid widening other fields, bypassing append_insn() etc.
This commit is contained in:
parent
8c07e983a2
commit
bb996692bd
@ -3389,8 +3389,15 @@ riscv_ip_hardcode (char *str,
|
||||
do
|
||||
{
|
||||
expression (imm_expr);
|
||||
if (imm_expr->X_op != O_constant)
|
||||
switch (imm_expr->X_op)
|
||||
{
|
||||
case O_constant:
|
||||
values[num++] = (insn_t) imm_expr->X_add_number;
|
||||
break;
|
||||
case O_big:
|
||||
values[num++] = generic_bignum[0];
|
||||
break;
|
||||
default:
|
||||
/* The first value isn't constant, so it should be
|
||||
.insn <type> <operands>. We have been parsed it
|
||||
in the riscv_ip. */
|
||||
@ -3398,9 +3405,8 @@ riscv_ip_hardcode (char *str,
|
||||
return error;
|
||||
return _("values must be constant");
|
||||
}
|
||||
values[num++] = (insn_t) imm_expr->X_add_number;
|
||||
}
|
||||
while (*input_line_pointer++ == ',' && num < 2);
|
||||
while (*input_line_pointer++ == ',' && num < 2 && imm_expr->X_op != O_big);
|
||||
|
||||
input_line_pointer--;
|
||||
if (*input_line_pointer != '\0')
|
||||
@ -3410,8 +3416,22 @@ riscv_ip_hardcode (char *str,
|
||||
insn->match = values[num - 1];
|
||||
create_insn (ip, insn);
|
||||
unsigned int bytes = riscv_insn_length (insn->match);
|
||||
if ((bytes < sizeof(values[0]) && values[num - 1] >> (8 * bytes) != 0)
|
||||
|| (num == 2 && values[0] != bytes))
|
||||
|
||||
if (num == 2 && values[0] != bytes)
|
||||
return _("value conflicts with instruction length");
|
||||
|
||||
if (imm_expr->X_op == O_big)
|
||||
{
|
||||
if (bytes != imm_expr->X_add_number * CHARS_PER_LITTLENUM)
|
||||
return _("value conflicts with instruction length");
|
||||
char *f = frag_more (bytes);
|
||||
for (num = 0; num < imm_expr->X_add_number; ++num)
|
||||
number_to_chars_littleendian (f + num * CHARS_PER_LITTLENUM,
|
||||
generic_bignum[num], CHARS_PER_LITTLENUM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bytes < sizeof(values[0]) && values[num - 1] >> (8 * bytes) != 0)
|
||||
return _("value conflicts with instruction length");
|
||||
|
||||
return NULL;
|
||||
@ -4476,7 +4496,7 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
|
||||
else
|
||||
as_bad ("%s `%s'", error.msg, error.statement);
|
||||
}
|
||||
else
|
||||
else if (imm_expr.X_op != O_big)
|
||||
{
|
||||
gas_assert (insn.insn_mo->pinfo != INSN_MACRO);
|
||||
append_insn (&insn, &imm_expr, imm_reloc);
|
||||
|
@ -65,8 +65,14 @@ insn.s +60 +0xac.*
|
||||
insn.s +61 +0xb0.*
|
||||
insn.s +62 +0xb6.*
|
||||
insn.s +63 +0xbe.*
|
||||
insn.s +64 +0xc0.*
|
||||
insn.s +65 +0xc4.*
|
||||
insn.s +66 +0xca.*
|
||||
insn.s +- +0xd2
|
||||
insn.s +64 +0xc8.*
|
||||
insn.s +65 +0xd4.*
|
||||
insn.s +66 +0xea.*
|
||||
insn.s +67 +0xec.*
|
||||
insn.s +68 +0xf0.*
|
||||
insn.s +69 +0xf6.*
|
||||
insn.s +70 +0xfe.*
|
||||
insn.s +71 +0x108.*
|
||||
insn.s +72 +0x114.*
|
||||
insn.s +- +0x12a
|
||||
#pass
|
||||
|
@ -5,3 +5,13 @@
|
||||
.*Error: unrecognized values `0x4,0x5,0x6'
|
||||
.*Error: value conflicts with instruction length `0x4,0x0001'
|
||||
.*Error: value conflicts with instruction length `0x2,0x00000013'
|
||||
.*Error: value conflicts with instruction length `0x10+1f'
|
||||
.*Error: value conflicts with instruction length `6,0x10+1f'
|
||||
.*Error: value conflicts with instruction length `0x10+3f'
|
||||
.*Error: value conflicts with instruction length `8,0x10+3f'
|
||||
.*Error: value conflicts with instruction length `0x10+7f'
|
||||
.*Error: value conflicts with instruction length `10,0x10+7f'
|
||||
.*Error: value conflicts with instruction length `0x10+107f'
|
||||
.*Error: value conflicts with instruction length `12,0x10+107f'
|
||||
.*Error: value conflicts with instruction length `0x10+607f'
|
||||
.*Error: value conflicts with instruction length `22,0x10+607f'
|
||||
|
@ -4,3 +4,13 @@
|
||||
.insn 0x4, 0x5, 0x6
|
||||
.insn 0x4, 0x0001
|
||||
.insn 0x2, 0x00000013
|
||||
.insn 0x100000000001f
|
||||
.insn 6, 0x100000000001f
|
||||
.insn 0x1000000000000003f
|
||||
.insn 8, 0x1000000000000003f
|
||||
.insn 0x10000000000000000007f
|
||||
.insn 10, 0x10000000000000000007f
|
||||
.insn 0x100000000000000000000107f
|
||||
.insn 12, 0x100000000000000000000107f
|
||||
.insn 0x10000000000000000000000000000000000000000607f
|
||||
.insn 22, 0x10000000000000000000000000000000000000000607f
|
||||
|
@ -63,7 +63,13 @@ Disassembly of section .text:
|
||||
[^:]+:[ ]+00000013[ ]+addi[ ]+zero,zero,0
|
||||
[^:]+:[ ]+001f 0000 0000[ ].*
|
||||
[^:]+:[ ]+0000003f 00000000[ ].*
|
||||
[^:]+:[ ]+007f 0000 0000 0000 0000[ ]+[._a-z].*
|
||||
[^:]+:[ ]+0000107f 00000000 00000000[ ]+[._a-z].*
|
||||
[^:]+:[ ]+607f 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000[ ]+[._a-z].*
|
||||
[^:]+:[ ]+0001[ ]+c\.addi[ ]+zero,0
|
||||
[^:]+:[ ]+00000013[ ]+addi[ ]+zero,zero,0
|
||||
[^:]+:[ ]+001f 0000 0000[ ].*
|
||||
[^:]+:[ ]+0000003f 00000000[ ].*
|
||||
[^:]+:[ ]+007f 0000 0000 0000 0000[ ]+[._a-z].*
|
||||
[^:]+:[ ]+0000107f 00000000 00000000[ ]+[._a-z].*
|
||||
[^:]+:[ ]+607f 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000[ ]+[._a-z].*
|
||||
|
@ -74,7 +74,21 @@ Disassembly of section .text:
|
||||
[^:]+:[ ]+00000013[ ]+nop
|
||||
[^:]+:[ ]+001f 0000 0000[ ].*
|
||||
[^:]+:[ ]+0000003f 00000000[ ].*
|
||||
[^:]+:[ ]+007f 0000 0000 0000[ ]+[._a-z].*
|
||||
[^:]+:[ ]+0000 ?
|
||||
[^:]+:[ ]+0000107f 00000000[ ]+[._a-z].*
|
||||
[^:]+:[ ]+00000000 ?
|
||||
[^:]+:[ ]+607f 0000 0000 0000[ ]+[._a-z].*
|
||||
[^:]+:[ ]+0000 0000 0000 0000 ?
|
||||
[^:]+:[ ]+0000 0000 0000 ?
|
||||
[^:]+:[ ]+0001[ ]+nop
|
||||
[^:]+:[ ]+00000013[ ]+nop
|
||||
[^:]+:[ ]+001f 0000 0000[ ].*
|
||||
[^:]+:[ ]+0000003f 00000000[ ].*
|
||||
[^:]+:[ ]+007f 0000 0000 0000[ ]+[._a-z].*
|
||||
[^:]+:[ ]+0000 ?
|
||||
[^:]+:[ ]+0000107f 00000000[ ]+[._a-z].*
|
||||
[^:]+:[ ]+00000000 ?
|
||||
[^:]+:[ ]+607f 0000 0000 0000[ ]+[._a-z].*
|
||||
[^:]+:[ ]+0000 0000 0000 0000 ?
|
||||
[^:]+:[ ]+0000 0000 0000 ?
|
||||
|
@ -60,7 +60,13 @@ target:
|
||||
.insn 0x00000013
|
||||
.insn 0x0000001f
|
||||
.insn 0x0000003f
|
||||
.insn 0x007f
|
||||
.insn 0x107f
|
||||
.insn 0x607f
|
||||
.insn 0x2, 0x0001
|
||||
.insn 0x4, 0x00000013
|
||||
.insn 6, 0x0000001f
|
||||
.insn 8, 0x0000003f
|
||||
.insn 10, 0x007f
|
||||
.insn 12, 0x107f
|
||||
.insn 22, 0x607f
|
||||
|
@ -37,6 +37,9 @@ static inline unsigned int riscv_insn_length (insn_t insn)
|
||||
return 6;
|
||||
if ((insn & 0x7f) == 0x3f) /* 64-bit instructions. */
|
||||
return 8;
|
||||
/* 80- ... 176-bit instructions. */
|
||||
if ((insn & 0x7f) == 0x7f && (insn & 0x7000) != 0x7000)
|
||||
return 10 + ((insn >> 11) & 0xe);
|
||||
/* Longer instructions not supported at the moment. */
|
||||
return 2;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user