diff options
author | Claudio Fontana <claudio.fontana@huawei.com> | 2013-10-10 10:55:05 +0200 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-04-25 13:19:57 +0100 |
commit | ffe856e406e85f14ff28a13814460b04f538c85d (patch) | |
tree | cd5c8bd17299dc3e2a77ba8fcfd6518226378f4e | |
parent | 0e85682c360c28ea832b41c862fe598a794c9b68 (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.risu | 19 | ||||
-rwxr-xr-x | risugen | 23 |
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) @@ -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($$) |