@@ -942,12 +942,12 @@ func signExtend(val int64, bit uint) int64 {
942
942
// result. For example, high may be used in LUI and low in a following ADDI to
943
943
// generate a full 32-bit constant.
944
944
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
947
947
}
948
948
949
949
// 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 {
951
951
return imm , 0 , nil
952
952
}
953
953
@@ -1007,26 +1007,41 @@ func regFAddr(a obj.Addr) uint32 {
1007
1007
return regAddr (a , REG_F0 , REG_F31 )
1008
1008
}
1009
1009
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 {
1013
1022
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
1017
1032
}
1018
1033
1019
1034
// immI extracts the signed integer of the specified size from an immediate.
1020
1035
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 ))
1023
1038
}
1024
1039
return uint32 (imm )
1025
1040
}
1026
1041
1027
1042
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 )
1030
1045
}
1031
1046
}
1032
1047
@@ -1058,8 +1073,8 @@ func wantFloatReg(ctxt *obj.Link, as obj.As, pos string, r uint32) {
1058
1073
1059
1074
// wantEvenOffset checks that the offset is a multiple of two.
1060
1075
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 )
1063
1078
}
1064
1079
}
1065
1080
@@ -1368,62 +1383,62 @@ func encodeRawIns(ins *instruction) uint32 {
1368
1383
}
1369
1384
1370
1385
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
1373
1388
}
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
1376
1391
}
1377
1392
return int64 (encodeBImmediate (uint32 (imm ))), nil
1378
1393
}
1379
1394
1380
1395
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
1383
1398
}
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
1386
1401
}
1387
1402
return int64 (encodeCBImmediate (uint32 (imm ))), nil
1388
1403
}
1389
1404
1390
1405
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
1393
1408
}
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
1396
1411
}
1397
1412
return int64 (encodeCJImmediate (uint32 (imm ))), nil
1398
1413
}
1399
1414
1400
1415
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
1403
1418
}
1404
1419
return imm << 20 , nil
1405
1420
}
1406
1421
1407
1422
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
1410
1425
}
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
1413
1428
}
1414
1429
return int64 (encodeJImmediate (uint32 (imm ))), nil
1415
1430
}
1416
1431
1417
1432
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
1420
1435
}
1421
1436
return ((imm >> 5 ) << 25 ) | ((imm & 0x1f ) << 7 ), nil
1422
1437
}
1423
1438
1424
1439
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
1427
1442
}
1428
1443
return imm << 12 , nil
1429
1444
}
@@ -1975,9 +1990,9 @@ func instructionsForMOV(p *obj.Prog) []*instruction {
1975
1990
// MOV $1, X10
1976
1991
// SLLI $63, X10, X10
1977
1992
var insSLLI * instruction
1978
- if ! immIFits (ins .imm , 32 ) {
1993
+ if err := immIFits (ins .imm , 32 ); err != nil {
1979
1994
ctz := bits .TrailingZeros64 (uint64 (ins .imm ))
1980
- if immIFits (ins .imm >> ctz , 32 ) {
1995
+ if err := immIFits (ins .imm >> ctz , 32 ); err == nil {
1981
1996
ins .imm = ins .imm >> ctz
1982
1997
insSLLI = & instruction {as : ASLLI , rd : ins .rd , rs1 : ins .rd , imm : int64 (ctz )}
1983
1998
}
0 commit comments