diff options
Diffstat (limited to 'gas/config/tc-riscv.c')
-rw-r--r-- | gas/config/tc-riscv.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index e915b82..6bd3b2f 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -1221,6 +1221,21 @@ arg_lookup (char **s, const char *const *array, size_t size, unsigned *regnop) return false; } +static bool +flt_lookup (float f, const float *array, size_t size, unsigned *regnop) +{ + size_t i; + + for (i = 0; i < size; i++) + if (array[i] == f) + { + *regnop = i; + return true; + } + + return false; +} + #define USE_BITS(mask,shift) (used_bits |= ((insn_t)(mask) << (shift))) #define USE_IMM(n, s) \ (used_bits |= ((insn_t)((1ull<<n)-1) << (s))) @@ -1401,6 +1416,14 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) goto unknown_validate_operand; } break; + case 'f': + switch (*++oparg) + { + case 'v': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break; + default: + goto unknown_validate_operand; + } + break; default: goto unknown_validate_operand; } @@ -3493,6 +3516,35 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, goto unknown_riscv_ip_operand; } break; + case 'f': + switch (*++oparg) + { + case 'v': + /* FLI.[HSDQ] value field for 'Zfa' extension. */ + if (!arg_lookup (&asarg, riscv_fli_symval, + ARRAY_SIZE (riscv_fli_symval), ®no)) + { + /* 0.0 is not a valid entry in riscv_fli_numval. */ + errno = 0; + float f = strtof (asarg, &asarg); + if (errno != 0 || f == 0.0 + || !flt_lookup (f, riscv_fli_numval, + ARRAY_SIZE(riscv_fli_numval), + ®no)) + { + as_bad (_("bad fli constant operand, " + "supported constants must be in " + "decimal or hexadecimal floating-point " + "literal form")); + break; + } + } + INSERT_OPERAND (RS1, *ip, regno); + continue; + default: + goto unknown_riscv_ip_operand; + } + break; default: goto unknown_riscv_ip_operand; } |