aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Fontana <claudio.fontana@huawei.com>2013-10-10 10:55:05 +0200
committerPeter Maydell <peter.maydell@linaro.org>2014-04-25 13:19:57 +0100
commitffe856e406e85f14ff28a13814460b04f538c85d (patch)
treecd5c8bd17299dc3e2a77ba8fcfd6518226378f4e
parent0e85682c360c28ea832b41c862fe598a794c9b68 (diff)
risugen: add register plus signed immediate addressing
new sextract function to extract a signed immediate from a field. Used in aarch64.risu for ldnp / stnp first, to implement the reg + 7bit signed offset immediate addressing. Signed-off-by: Claudio Fontana <claudio.fontana@linaro.org>
-rw-r--r--aarch64.risu19
-rwxr-xr-xrisugen23
2 files changed, 32 insertions, 10 deletions
diff --git a/aarch64.risu b/aarch64.risu
index d4a5f59..88e370b 100644
--- a/aarch64.risu
+++ b/aarch64.risu
@@ -228,7 +228,7 @@ LDAXP64 A64 11 001000 011 11111 1 rtt:5 rn:5 rt:5 \
# C3.3.7 Load/store no-allocate pair (offset)
# 31 30 29 28 27 26 25 24 23 22 21 15 14 10 9 5 4 0
-# opc 1 0 1 V 0 0 0 L imm7 Rt2 Rn Rt
+# opc 1 0 1 V 0 0 0 L simm7 Rt2 Rn Rt
#
# opc V L
# 00 0 0 STNP 32-bit
@@ -236,22 +236,21 @@ LDAXP64 A64 11 001000 011 11111 1 rtt:5 rn:5 rt:5 \
# 10 0 0 STNP 64-bit
# 10 0 1 LDNP 64-bit
-# XXX imm7 is always zero for now
-STNP32 A64 00 101 0 000 0 0000000 rtt:5 rn:5 rt:5 \
+STNP32 A64 00 101 0 000 0 imm:7 rtt:5 rn:5 rt:5 \
!constraints { $rn != 31 && $rn != $rt && $rn != $rtt; } \
-!memory { align(8); reg($rn); }
+!memory { align(8); reg_plus_imm($rn, sextract($imm, 7) * 4); }
-LDNP32 A64 00 101 0 000 1 0000000 rtt:5 rn:5 rt:5 \
+LDNP32 A64 00 101 0 000 1 imm:7 rtt:5 rn:5 rt:5 \
!constraints { $rn != 31 && $rt != $rtt && $rn != $rt && $rn != $rtt; } \
-!memory { align(8); reg($rn); }
+!memory { align(8); reg_plus_imm($rn, sextract($imm, 7) * 4); }
-STNP64 A64 10 101 0 000 0 0000000 rtt:5 rn:5 rt:5 \
+STNP64 A64 10 101 0 000 0 imm:7 rtt:5 rn:5 rt:5 \
!constraints { $rn != 31 && $rn != $rt && $rn != $rtt; } \
-!memory { align(16); reg($rn); }
+!memory { align(16); reg_plus_imm($rn, sextract($imm, 7) * 8); }
-LDNP64 A64 10 101 0 000 1 0000000 rtt:5 rn:5 rt:5 \
+LDNP64 A64 10 101 0 000 1 imm:7 rtt:5 rn:5 rt:5 \
!constraints { $rn != 31 && $rt != $rtt && $rn != $rt && $rn != $rtt; } \
-!memory { align(16); reg($rn); }
+!memory { align(16); reg_plus_imm($rn, sextract($imm, 7) * 8); }
# - - - 1 0 0 - - - - - - - - - - - - - - - - Data processing - immediate
# C3.4.1 Add/subtract (immediate)
diff --git a/risugen b/risugen
index 333d18e..a303f39 100755
--- a/risugen
+++ b/risugen
@@ -188,6 +188,24 @@ sub write_switch_to_test_mode()
}
}
+# sign extend a 32bit reg into a 64bit reg
+sub write_sxt32($$)
+{
+ my ($rd, $rn) = @_;
+ die "write_sxt32: invalid operation for this arch.\n" if (!$is_aarch64);
+
+ insn32(0x93407c00 | $rn << 5 | $rd);
+}
+
+# sign-extract from a nbit optionally signed bitfield
+sub sextract($$)
+{
+ my ($field, $nbits) = @_;
+
+ my $sign = $field & (1 << ($nbits - 1));
+ return -$sign + ($field ^ $sign);
+}
+
sub write_sub_rrr($$$)
{
my ($rd, $rn, $rm) = @_;
@@ -289,6 +307,11 @@ sub write_mov_ri($$)
write_mov_ri16($rd, ($imm & 0xffff), 0);
my $highhalf = ($imm >> 16) & 0xffff;
write_mov_ri16($rd, $highhalf, 1) if $highhalf;
+
+ if ($is_aarch64 && $imm < 0) {
+ # sign extend to allow small negative imm constants
+ write_sxt32($rd, $rd);
+ }
}
sub aarch64_limm($$)