! construct a new ##load-memory or ##store-memory with the
! ##add's operand as the displacement
: fuse-displacement? ( insn -- ? )
- base>> vreg>insn ##add? ;
+ {
+ [ offset>> 0 = complex-addressing? or ]
+ [ base>> vreg>insn ##add? ]
+ } 1&& ;
GENERIC: alien-insn-value ( insn -- value )
[ >>displacement ] [ >>scale ] bi* ;
: rewrite-memory-op ( insn -- insn/f )
- {
- { [ dup fuse-base-offset? ] [ fuse-base-offset ] }
- { [ dup fuse-displacement-offset? ] [ fuse-displacement-offset ] }
- { [ dup fuse-scale? ] [ fuse-scale ] }
- [ drop f ]
- } cond ;
+ complex-addressing? [
+ {
+ { [ dup fuse-base-offset? ] [ fuse-base-offset ] }
+ { [ dup fuse-displacement-offset? ] [ fuse-displacement-offset ] }
+ { [ dup fuse-scale? ] [ fuse-scale ] }
+ [ drop f ]
+ } cond
+ ] [ drop f ] if ;
: rewrite-memory-imm-op ( insn -- insn/f )
{
} value-numbering-step
] unit-test
-! Base offset fusion on ##load/store-memory
+! Base offset fusion on ##load/store-memory -- only on x86
+cpu x86?
[
V{
T{ ##peek f 0 D 0 }
T{ ##add-imm f 4 2 31337 }
T{ ##load-memory f 5 2 3 0 31337 int-rep c:uchar }
}
-] [
+]
+[
+ V{
+ T{ ##peek f 0 D 0 }
+ T{ ##peek f 1 D 1 }
+ T{ ##tagged>integer f 2 0 }
+ T{ ##tagged>integer f 3 1 }
+ T{ ##add-imm f 4 2 31337 }
+ T{ ##load-memory f 5 4 3 0 0 int-rep c:uchar }
+ }
+] ?
+[
V{
T{ ##peek f 0 D 0 }
T{ ##peek f 1 D 1 }
} value-numbering-step
] unit-test
-! Displacement offset fusion on ##load/store-memory
+! Displacement offset fusion on ##load/store-memory -- only on x86
+cpu x86?
[
V{
T{ ##peek f 0 D 0 }
T{ ##add-imm f 4 3 31337 }
T{ ##load-memory f 5 2 3 0 31338 int-rep c:uchar }
}
-] [
+]
+[
+ V{
+ T{ ##peek f 0 D 0 }
+ T{ ##peek f 1 D 1 }
+ T{ ##tagged>integer f 2 0 }
+ T{ ##tagged>integer f 3 1 }
+ T{ ##add-imm f 4 3 31337 }
+ T{ ##load-memory f 5 2 4 0 1 int-rep c:uchar }
+ }
+] ?
+[
V{
T{ ##peek f 0 D 0 }
T{ ##peek f 1 D 1 }
] unit-test
! Scale fusion on ##load/store-memory
+cpu x86?
[
V{
T{ ##peek f 0 D 0 }
T{ ##shl-imm f 4 3 2 }
T{ ##load-memory f 5 2 3 2 0 int-rep c:uchar }
}
-] [
+]
+[
V{
T{ ##peek f 0 D 0 }
T{ ##peek f 1 D 1 }
T{ ##tagged>integer f 3 1 }
T{ ##shl-imm f 4 3 2 }
T{ ##load-memory f 5 2 4 0 0 int-rep c:uchar }
- } value-numbering-step
-] unit-test
-
-! Don't do scale fusion if there's already a scale
-[ ] [
+ }
+] ?
+[
V{
T{ ##peek f 0 D 0 }
T{ ##peek f 1 D 1 }
T{ ##tagged>integer f 2 0 }
T{ ##tagged>integer f 3 1 }
T{ ##shl-imm f 4 3 2 }
- T{ ##load-memory f 5 2 4 1 0 int-rep c:uchar }
- } dup value-numbering-step assert=
-] unit-test
-
-! Don't do scale fusion if the scale factor is out of range
-[ ] [
- V{
- T{ ##peek f 0 D 0 }
- T{ ##peek f 1 D 1 }
- T{ ##tagged>integer f 2 0 }
- T{ ##tagged>integer f 3 1 }
- T{ ##shl-imm f 4 3 4 }
T{ ##load-memory f 5 2 4 0 0 int-rep c:uchar }
- } dup value-numbering-step assert=
+ } value-numbering-step
] unit-test
+
+cpu x86? [
+ ! Don't do scale fusion if there's already a scale
+ [ ] [
+ V{
+ T{ ##peek f 0 D 0 }
+ T{ ##peek f 1 D 1 }
+ T{ ##tagged>integer f 2 0 }
+ T{ ##tagged>integer f 3 1 }
+ T{ ##shl-imm f 4 3 2 }
+ T{ ##load-memory f 5 2 4 1 0 int-rep c:uchar }
+ } dup value-numbering-step assert=
+ ] unit-test
+
+ ! Don't do scale fusion if the scale factor is out of range
+ [ ] [
+ V{
+ T{ ##peek f 0 D 0 }
+ T{ ##peek f 1 D 1 }
+ T{ ##tagged>integer f 2 0 }
+ T{ ##tagged>integer f 3 1 }
+ T{ ##shl-imm f 4 3 4 }
+ T{ ##load-memory f 5 2 4 0 0 int-rep c:uchar }
+ } dup value-numbering-step assert=
+ ] unit-test
+] when