aboutsummaryrefslogtreecommitdiff
path: root/arm64-gen.c
diff options
context:
space:
mode:
authorEdmund Grimley Evans <Edmund.Grimley.Evans@gmail.com>2015-03-02 20:51:03 +0000
committerEdmund Grimley Evans <Edmund.Grimley.Evans@gmail.com>2015-03-02 20:51:03 +0000
commit1706d2254b168309b2c38985750b6d00ad254ef3 (patch)
tree15e7158c19bb59986e89442018f5f96d0e71b340 /arm64-gen.c
parent1d41da959006cf9695c505a5bd6a6e4c08bfd9f4 (diff)
downloadtinycc-1706d2254b168309b2c38985750b6d00ad254ef3.tar.gz
tinycc-1706d2254b168309b2c38985750b6d00ad254ef3.tar.bz2
arm64-gen.c: Improve generation of stack offsets.
Diffstat (limited to 'arm64-gen.c')
-rw-r--r--arm64-gen.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/arm64-gen.c b/arm64-gen.c
index 630556d..5444f29 100644
--- a/arm64-gen.c
+++ b/arm64-gen.c
@@ -274,8 +274,16 @@ static int arm64_type_size(int t)
static void arm64_spoff(int reg, uint64_t off)
{
- arm64_movimm(30, off); // use x30 for offset
- o(0x8b3e63e0 | reg); // add x(reg),sp,x30
+ uint32_t sub = off >> 63;
+ if (sub)
+ off = -off;
+ if (off < 4096)
+ o(0x910003e0 | sub << 30 | reg | off << 10);
+ // (add|sub) x(reg),sp,#(off)
+ else {
+ arm64_movimm(30, off); // use x30 for offset
+ o(0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30
+ }
}
static void arm64_ldrx(int sg, int sz, int dst, int bas, uint64_t off)