Skip to content

Commit 38b2c06

Browse files
committed
cmd/internal/obj/riscv: clean up immediate checking
Change immIFits to return an error in the case that it does not fit. This allows for deduplication and consistency of error messages. Additionally, since we've already calculated the min and max values, we can easily include these in the message. Also provide and use immEven, for the same reasons. Change-Id: Ie680558744f3e9bc19d6913c4144ce9ddbd0429c Reviewed-on: https://go-review.googlesource.com/c/go/+/523458 Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Mark Ryan <[email protected]> Run-TryBot: M Zhuo <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: M Zhuo <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent 561a507 commit 38b2c06

File tree

1 file changed

+54
-39
lines changed
  • src/cmd/internal/obj/riscv

1 file changed

+54
-39
lines changed

src/cmd/internal/obj/riscv/obj.go

Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -942,12 +942,12 @@ func signExtend(val int64, bit uint) int64 {
942942
// result. For example, high may be used in LUI and low in a following ADDI to
943943
// generate a full 32-bit constant.
944944
func Split32BitImmediate(imm int64) (low, high int64, err error) {
945-
if !immIFits(imm, 32) {
946-
return 0, 0, fmt.Errorf("immediate does not fit in 32 bits: %d", imm)
945+
if err := immIFits(imm, 32); err != nil {
946+
return 0, 0, err
947947
}
948948

949949
// Nothing special needs to be done if the immediate fits in 12 bits.
950-
if immIFits(imm, 12) {
950+
if err := immIFits(imm, 12); err == nil {
951951
return imm, 0, nil
952952
}
953953

@@ -1007,26 +1007,41 @@ func regFAddr(a obj.Addr) uint32 {
10071007
return regAddr(a, REG_F0, REG_F31)
10081008
}
10091009

1010-
// immIFits reports whether immediate value x fits in nbits bits
1011-
// as a signed integer.
1012-
func immIFits(x int64, nbits uint) bool {
1010+
// immEven checks that the immediate is a multiple of two. If it
1011+
// is not, an error is returned.
1012+
func immEven(x int64) error {
1013+
if x&1 != 0 {
1014+
return fmt.Errorf("immediate %#x is not a multiple of two", x)
1015+
}
1016+
return nil
1017+
}
1018+
1019+
// immIFits checks whether the immediate value x fits in nbits bits
1020+
// as a signed integer. If it does not, an error is returned.
1021+
func immIFits(x int64, nbits uint) error {
10131022
nbits--
1014-
var min int64 = -1 << nbits
1015-
var max int64 = 1<<nbits - 1
1016-
return min <= x && x <= max
1023+
min := int64(-1) << nbits
1024+
max := int64(1)<<nbits - 1
1025+
if x < min || x > max {
1026+
if nbits <= 16 {
1027+
return fmt.Errorf("signed immediate %d must be in range [%d, %d] (%d bits)", x, min, max, nbits)
1028+
}
1029+
return fmt.Errorf("signed immediate %#x must be in range [%#x, %#x] (%d bits)", x, min, max, nbits)
1030+
}
1031+
return nil
10171032
}
10181033

10191034
// immI extracts the signed integer of the specified size from an immediate.
10201035
func immI(as obj.As, imm int64, nbits uint) uint32 {
1021-
if !immIFits(imm, nbits) {
1022-
panic(fmt.Sprintf("%v: signed immediate %d cannot fit in %d bits", as, imm, nbits))
1036+
if err := immIFits(imm, nbits); err != nil {
1037+
panic(fmt.Sprintf("%v: %v", as, err))
10231038
}
10241039
return uint32(imm)
10251040
}
10261041

10271042
func wantImmI(ctxt *obj.Link, as obj.As, imm int64, nbits uint) {
1028-
if !immIFits(imm, nbits) {
1029-
ctxt.Diag("%v: signed immediate %d cannot be larger than %d bits", as, imm, nbits)
1043+
if err := immIFits(imm, nbits); err != nil {
1044+
ctxt.Diag("%v: %v", as, err)
10301045
}
10311046
}
10321047

@@ -1058,8 +1073,8 @@ func wantFloatReg(ctxt *obj.Link, as obj.As, pos string, r uint32) {
10581073

10591074
// wantEvenOffset checks that the offset is a multiple of two.
10601075
func wantEvenOffset(ctxt *obj.Link, as obj.As, offset int64) {
1061-
if offset%1 != 0 {
1062-
ctxt.Diag("%v: jump offset %d must be a multiple of two", as, offset)
1076+
if err := immEven(offset); err != nil {
1077+
ctxt.Diag("%v: %v", as, err)
10631078
}
10641079
}
10651080

@@ -1368,62 +1383,62 @@ func encodeRawIns(ins *instruction) uint32 {
13681383
}
13691384

13701385
func EncodeBImmediate(imm int64) (int64, error) {
1371-
if !immIFits(imm, 13) {
1372-
return 0, fmt.Errorf("immediate %#x does not fit in 13 bits", imm)
1386+
if err := immIFits(imm, 13); err != nil {
1387+
return 0, err
13731388
}
1374-
if imm&1 != 0 {
1375-
return 0, fmt.Errorf("immediate %#x is not a multiple of two", imm)
1389+
if err := immEven(imm); err != nil {
1390+
return 0, err
13761391
}
13771392
return int64(encodeBImmediate(uint32(imm))), nil
13781393
}
13791394

13801395
func EncodeCBImmediate(imm int64) (int64, error) {
1381-
if !immIFits(imm, 9) {
1382-
return 0, fmt.Errorf("immediate %#x does not fit in 9 bits", imm)
1396+
if err := immIFits(imm, 9); err != nil {
1397+
return 0, err
13831398
}
1384-
if imm&1 != 0 {
1385-
return 0, fmt.Errorf("immediate %#x is not a multiple of two", imm)
1399+
if err := immEven(imm); err != nil {
1400+
return 0, err
13861401
}
13871402
return int64(encodeCBImmediate(uint32(imm))), nil
13881403
}
13891404

13901405
func EncodeCJImmediate(imm int64) (int64, error) {
1391-
if !immIFits(imm, 12) {
1392-
return 0, fmt.Errorf("immediate %#x does not fit in 12 bits", imm)
1406+
if err := immIFits(imm, 12); err != nil {
1407+
return 0, err
13931408
}
1394-
if imm&1 != 0 {
1395-
return 0, fmt.Errorf("immediate %#x is not a multiple of two", imm)
1409+
if err := immEven(imm); err != nil {
1410+
return 0, err
13961411
}
13971412
return int64(encodeCJImmediate(uint32(imm))), nil
13981413
}
13991414

14001415
func EncodeIImmediate(imm int64) (int64, error) {
1401-
if !immIFits(imm, 12) {
1402-
return 0, fmt.Errorf("immediate %#x does not fit in 12 bits", imm)
1416+
if err := immIFits(imm, 12); err != nil {
1417+
return 0, err
14031418
}
14041419
return imm << 20, nil
14051420
}
14061421

14071422
func EncodeJImmediate(imm int64) (int64, error) {
1408-
if !immIFits(imm, 21) {
1409-
return 0, fmt.Errorf("immediate %#x does not fit in 21 bits", imm)
1423+
if err := immIFits(imm, 21); err != nil {
1424+
return 0, err
14101425
}
1411-
if imm&1 != 0 {
1412-
return 0, fmt.Errorf("immediate %#x is not a multiple of two", imm)
1426+
if err := immEven(imm); err != nil {
1427+
return 0, err
14131428
}
14141429
return int64(encodeJImmediate(uint32(imm))), nil
14151430
}
14161431

14171432
func EncodeSImmediate(imm int64) (int64, error) {
1418-
if !immIFits(imm, 12) {
1419-
return 0, fmt.Errorf("immediate %#x does not fit in 12 bits", imm)
1433+
if err := immIFits(imm, 12); err != nil {
1434+
return 0, err
14201435
}
14211436
return ((imm >> 5) << 25) | ((imm & 0x1f) << 7), nil
14221437
}
14231438

14241439
func EncodeUImmediate(imm int64) (int64, error) {
1425-
if !immIFits(imm, 20) {
1426-
return 0, fmt.Errorf("immediate %#x does not fit in 20 bits", imm)
1440+
if err := immIFits(imm, 20); err != nil {
1441+
return 0, err
14271442
}
14281443
return imm << 12, nil
14291444
}
@@ -1975,9 +1990,9 @@ func instructionsForMOV(p *obj.Prog) []*instruction {
19751990
// MOV $1, X10
19761991
// SLLI $63, X10, X10
19771992
var insSLLI *instruction
1978-
if !immIFits(ins.imm, 32) {
1993+
if err := immIFits(ins.imm, 32); err != nil {
19791994
ctz := bits.TrailingZeros64(uint64(ins.imm))
1980-
if immIFits(ins.imm>>ctz, 32) {
1995+
if err := immIFits(ins.imm>>ctz, 32); err == nil {
19811996
ins.imm = ins.imm >> ctz
19821997
insSLLI = &instruction{as: ASLLI, rd: ins.rd, rs1: ins.rd, imm: int64(ctz)}
19831998
}

0 commit comments

Comments
 (0)