In RISC-V assembly, there's a fictitious 4-operand ADD that's used to add a TP-relative relocation. It's usually used like "add a0,a0,tp,%tprel_add(sym)", but binutils allows a plain 0 as the 4th operand:
$ cat test.s
add a0, a0, tp, 0
$ riscv32-unknown-elf-as test.s
Is this just loose error checking, or is it actually needed in some cases? There's a patch for TLS support in LLVM that requires the presence of %tprel_add in the 4-operand add. It's important, then, to clarify if the "add a0,a0,tp,0" should be accepted or not.
I consider it a bug, but not serious enough that I had gotten around to trying to fix it yet. The support for the 4-operand add is overloaded with the amo* instruction support that requires addresses with a constant 0 immediate offset. It is an odd design. I don't know why it was done this way. The fact that we accept 0 for an amo* instruction is why zero gets accepted for the 4-operand add, which looked like a fairly harmless bug to me. But looking at this closer, I see that the same overload means that we can use %tprel_add in an amo* instruction, which is a more serious problem that I think justifies a fix now.
rohan:2097$ cat tmp2.s
.type i, @object
.size i, 4
rohan:2098$ ./as-new tmp2.s
rohan:2099$ ../binutils/objdump -dr a.out
a.out: file format elf32-littleriscv
Disassembly of section .text:
0: 0095242f amoadd.w s0,s1,(a0)
0: R_RISCV_TPREL_ADD i
0: R_RISCV_RELAX *ABS*
The master branch has been updated by Jim Wilson <firstname.lastname@example.org>:
Author: Jim Wilson <email@example.com>
Date: Fri Dec 7 12:31:05 2018 -0800
RISC-V: Fix 4-arg add parsing.
* config/tc-riscv.c (validate_riscv_insn) <'1'>: New case.
(riscv_ip) <'j'>: Set imm_reloc before p.
<'1'>: New case.
<'0'>: Use percent_op_null and don't set imm_reloc.
<alu_op>: Handle *args == '1'.
* testsuite/gas/riscv/tprel-add.d: New.
* testsuite/gas/riscv/tprel-add.l: New.
* testsuite/gas/riscv/tprel-add.s: New.
* riscv-opc.c (riscv_opcodes) <"add">: Use 1 not 0 for fourth arg.