Index: lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -425,7 +425,7 @@ IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); else IsValid = isInt<12>(Imm); - return IsValid && (VK == RISCVMCExpr::VK_RISCV_None || + return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) || VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO); } @@ -795,8 +795,10 @@ Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, "immediate must be a multiple of 16 bytes and non-zero in the range"); case Match_InvalidSImm12: - return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11), - (1 << 11) - 1); + return generateImmOutOfRangeError( + Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, + "operand must be a symbol with %lo/%pcrel_lo modifier or an integer in " + "the range"); case Match_InvalidSImm12Lsb0: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, Index: test/MC/RISCV/rv32d-invalid.s =================================================================== --- test/MC/RISCV/rv32d-invalid.s +++ test/MC/RISCV/rv32d-invalid.s @@ -2,12 +2,12 @@ # Out of range immediates ## simm12 -fld ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047] -fsd ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047] +fld ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] +fsd ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] # Memory operand not formatted correctly -fld ft1, a0, -200 # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047] -fsd ft2, a1, 100 # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047] +fld ft1, a0, -200 # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] +fsd ft2, a1, 100 # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] # Invalid register names fld ft15, 100(a0) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction Index: test/MC/RISCV/rv32f-invalid.s =================================================================== --- test/MC/RISCV/rv32f-invalid.s +++ test/MC/RISCV/rv32f-invalid.s @@ -2,12 +2,12 @@ # Out of range immediates ## simm12 -flw ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047] -fsw ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047] +flw ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] +fsw ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] # Memory operand not formatted correctly -flw ft1, a0, -200 # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047] -fsw ft2, a1, 100 # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-2048, 2047] +flw ft1, a0, -200 # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] +fsw ft2, a1, 100 # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] # Invalid register names flw ft15, 100(a0) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction Index: test/MC/RISCV/rv32i-invalid.s =================================================================== --- test/MC/RISCV/rv32i-invalid.s +++ test/MC/RISCV/rv32i-invalid.s @@ -16,8 +16,8 @@ csrrci x0, 43, -90 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31] ## simm12 -ori a0, a1, -2049 # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-2048, 2047] -andi ra, sp, 2048 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [-2048, 2047] +ori a0, a1, -2049 # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] +andi ra, sp, 2048 # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] ## uimm12 csrrw a0, -1, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] @@ -66,10 +66,11 @@ csrrci x0, 43, %pcrel_lo(d) # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31] ## simm12 -ori a0, a1, %hi(foo) # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-2048, 2047] -andi ra, sp, %pcrel_hi(123) # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [-2048, 2047] -xori a2, a3, %hi(345) # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [-2048, 2047] -add a1, a2, (a3) # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-2048, 2047] +ori a0, a1, %hi(foo) # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] +andi ra, sp, %pcrel_hi(123) # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] +xori a2, a3, %hi(345) # CHECK: :[[@LINE]]:14: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] +add a1, a2, (a3) # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] +add a1, a2, foo # CHECK: :[[@LINE]]:13: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] ## uimm12 csrrw a0, %lo(1), a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] @@ -146,7 +147,7 @@ sltiu s2, s3, 0x50, 0x60 # CHECK: :[[@LINE]]:21: error: invalid operand for instruction # Memory operand not formatted correctly -lw a4, a5, 111 # CHECK: :[[@LINE]]:8: error: immediate must be an integer in the range [-2048, 2047] +lw a4, a5, 111 # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] # Too few operands ori a0, a1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction Index: test/MC/RISCV/rv32i-valid.s =================================================================== --- test/MC/RISCV/rv32i-valid.s +++ test/MC/RISCV/rv32i-valid.s @@ -111,12 +111,16 @@ # CHECK-ASM-AND-OBJ: lw a0, 97(a2) # CHECK-ASM: encoding: [0x03,0x25,0x16,0x06] lw a0, 97(a2) -# CHECK-ASM-AND-OBJ: lbu s5, 0(s6) -# CHECK-ASM: encoding: [0x83,0x4a,0x0b,0x00] -lbu s5, 0(s6) -# CHECK-ASM-AND-OBJ: lhu t3, 255(t3) -# CHECK-ASM: encoding: [0x03,0x5e,0xfe,0x0f] -lhu t3, 255(t3) +# CHECK-ASM: lbu s5, %lo(foo)(s6) +# CHECK-ASM: encoding: [0x83,0x4a,0bAAAA1011,A] +# CHECK-OBJ: lbu s5, 0(s6) +# CHECK-OBJ: R_RISCV_LO12 +lbu s5, %lo(foo)(s6) +# CHECK-ASM: lhu t3, %pcrel_lo(foo)(t3) +# CHECK-ASM: encoding: [0x03,0x5e,0bAAAA1110,A] +# CHECK-OBJ: lhu t3, 0(t3) +# CHECK-OBJ: R_RISCV_PCREL_LO12 +lhu t3, %pcrel_lo(foo)(t3) # CHECK-ASM-AND-OBJ: sb a0, 2047(a2) # CHECK-ASM: encoding: [0xa3,0x0f,0xa6,0x7e] @@ -134,6 +138,11 @@ # CHECK-ASM-AND-OBJ: addi ra, sp, 2 # CHECK-ASM: encoding: [0x93,0x00,0x21,0x00] addi ra, sp, 2 +# CHECK-ASM: addi ra, sp, %lo(foo) +# CHECK-ASM: encoding: [0x93,0x00,0bAAAA0001,A] +# CHECK-OBJ: addi ra, sp, 0 +# CHECK-OBJ: R_RISCV_LO12 +addi ra, sp, %lo(foo) # CHECK-ASM-AND-OBJ: slti a0, a2, -20 # CHECK-ASM: encoding: [0x13,0x25,0xc6,0xfe] slti a0, a2, -20 Index: test/MC/RISCV/rv64i-invalid.s =================================================================== --- test/MC/RISCV/rv64i-invalid.s +++ test/MC/RISCV/rv64i-invalid.s @@ -7,8 +7,8 @@ sraiw a0, a0, -19 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31] ## simm12 -addiw a0, a1, -2049 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [-2048, 2047] -ld ra, 2048(sp) # CHECK: :[[@LINE]]:8: error: immediate must be an integer in the range [-2048, 2047] +addiw a0, a1, -2049 # CHECK: :[[@LINE]]:15: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] +ld ra, 2048(sp) # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047] # Illegal operand modifier ## uimm5 @@ -17,4 +17,4 @@ sraiw a0, a0, %hi(2) # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31] ## simm12 -addiw a0, a1, %hi(foo) # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [-2048, 2047] +addiw a0, a1, %hi(foo) # CHECK: :[[@LINE]]:15: error: operand must be a symbol with %lo/%pcrel_lo modifier or an integer in the range [-2048, 2047]