[PATCH v1] LoongArch: Warn about right shifts of negative numbers
Lulu Cai
cailulu@loongson.cn
Thu Apr 3 02:37:43 GMT 2025
The GNU Assembler User Guide says that the right shift operator ">>"
in an expression is the same as the C operator.
On LoongArch the assembler directives and instructions do not treat
negative numbers ">>" the same way. The directives treats negative
numbers ">>" as logical right shifts while the instructions treats them
as arithmetic right shifts.
The right shift of negative numbers in the instructions may be changed
from an arithmetic right shift to a logical right shift in the future,
and a warning is issued for this.
---
gas/config/loongarch-parse.y | 3 ++
gas/testsuite/gas/loongarch/loongarch.exp | 1 +
.../gas/loongarch/negative_right_shift.d | 40 +++++++++++++++++++
.../gas/loongarch/negative_right_shift.l | 13 ++++++
.../gas/loongarch/negative_right_shift.s | 32 +++++++++++++++
5 files changed, 89 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/negative_right_shift.d
create mode 100644 gas/testsuite/gas/loongarch/negative_right_shift.l
create mode 100644 gas/testsuite/gas/loongarch/negative_right_shift.s
diff --git a/gas/config/loongarch-parse.y b/gas/config/loongarch-parse.y
index ac35deee1de..97055fe42c3 100644
--- a/gas/config/loongarch-parse.y
+++ b/gas/config/loongarch-parse.y
@@ -225,6 +225,9 @@ emit_bin (int op)
opr1 = opr1 << opr2;
break;
case RIGHT_OP:
+ if (opr1 < 0)
+ as_warn(_("Right shift of negative numbers may be changed "
+ "from arithmetic right shift to logical right shift!"));
/* Algorithm right shift. */
opr1 = (offsetT)opr1 >> (offsetT)opr2;
break;
diff --git a/gas/testsuite/gas/loongarch/loongarch.exp b/gas/testsuite/gas/loongarch/loongarch.exp
index 87595b91cce..0e836f7f217 100644
--- a/gas/testsuite/gas/loongarch/loongarch.exp
+++ b/gas/testsuite/gas/loongarch/loongarch.exp
@@ -36,5 +36,6 @@ if [istarget loongarch*-*-*] {
if [istarget loongarch64-*-*] {
run_list_test "illegal-operand"
run_list_test "pseudo_op_option_fail"
+ run_list_test "negative_right_shift"
}
}
diff --git a/gas/testsuite/gas/loongarch/negative_right_shift.d b/gas/testsuite/gas/loongarch/negative_right_shift.d
new file mode 100644
index 00000000000..4237710c2b3
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/negative_right_shift.d
@@ -0,0 +1,40 @@
+#as:
+#objdump: -d
+#skip: loongarch32-*-*
+#warning_output: negative_right_shift.l
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+0+ <directives>:
+ 0: 03400000 nop
+ 4: 00000001 \.word 0x00000001
+ 8: 00000001 \.word 0x00000001
+
+0+c <insns>:
+ c: 02bff9ac addi.w \$t0, \$t1, -2
+ 10: 02fff9ac addi.d \$t0, \$t1, -2
+ 14: 13fff9ac addu16i.d \$t0, \$t1, -2
+ 18: 15ffffcc lu12i.w \$t0, -2
+ 1c: 17ffffcc lu32i.d \$t0, -2
+ 20: 033ff9ac lu52i.d \$t0, \$t1, -2
+ 24: 023ff9ac slti \$t0, \$t1, -2
+ 28: 027ff9ac sltui \$t0, \$t1, -2
+ 2c: 19ffffcc pcaddi \$t0, -2
+ 30: 1dffffcc pcaddu12i \$t0, -2
+ 34: 1fffffcc pcaddu18i \$t0, -2
+ 38: 1bffffcc pcalau12i \$t0, -2
+ 3c: 02bffdac addi.w \$t0, \$t1, -1
+ 40: 02fffdac addi.d \$t0, \$t1, -1
+ 44: 13fffdac addu16i.d \$t0, \$t1, -1
+ 48: 15ffffec lu12i.w \$t0, -1
+ 4c: 17ffffec lu32i.d \$t0, -1
+ 50: 033ffdac lu52i.d \$t0, \$t1, -1
+ 54: 023ffdac slti \$t0, \$t1, -1
+ 58: 027ffdac sltui \$t0, \$t1, -1
+ 5c: 19ffffec pcaddi \$t0, -1
+ 60: 1dffffec pcaddu12i \$t0, -1
+ 64: 1fffffec pcaddu18i \$t0, -1
+ 68: 1bffffec pcalau12i \$t0, -1
diff --git a/gas/testsuite/gas/loongarch/negative_right_shift.l b/gas/testsuite/gas/loongarch/negative_right_shift.l
new file mode 100644
index 00000000000..6edb2a5ebf8
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/negative_right_shift.l
@@ -0,0 +1,13 @@
+.*: Assembler messages:
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
diff --git a/gas/testsuite/gas/loongarch/negative_right_shift.s b/gas/testsuite/gas/loongarch/negative_right_shift.s
new file mode 100644
index 00000000000..c6a8a1e7c6e
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/negative_right_shift.s
@@ -0,0 +1,32 @@
+directives:
+.align -1>>62
+.word -1>>63
+.4byte -1>>63
+
+insns:
+addi.w $t0, $t1, -1<<1
+addi.d $t0, $t1, -1<<1
+addu16i.d $t0, $t1, -1<<1
+lu12i.w $t0, -1<<1
+lu32i.d $t0, -1<<1
+lu52i.d $t0, $t1, -1<<1
+slti $t0, $t1, -1<<1
+sltui $t0, $t1, -1<<1
+pcaddi $t0, -1<<1
+pcaddu12i $t0, -1<<1
+pcaddu18i $t0, -1<<1
+pcalau12i $t0, -1<<1
+
+# warn
+addi.w $t0, $t1, -1>>63
+addi.d $t0, $t1, -1>>63
+addu16i.d $t0, $t1, -1>>63
+lu12i.w $t0, -1>>63
+lu32i.d $t0, -1>>63
+lu52i.d $t0, $t1, -1>>63
+slti $t0, $t1, -1>>63
+sltui $t0, $t1, -1>>63
+pcaddi $t0, -1>>63
+pcaddu12i $t0, -1>>63
+pcaddu18i $t0, -1>>63
+pcalau12i $t0, -1>>63
--
2.38.1
More information about the Binutils
mailing list