diff options
| author | Tamás Hadházy <85063808+Hels15@users.noreply.github.com> | 2025-03-23 17:10:41 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-23 10:10:41 -0700 |
| commit | 3e17e811c4429cda194ccdb892ddb2bd10fa71ea (patch) | |
| tree | a37fbf64ef0871d8b755e8f71857dace051e7149 /chapter21/src/main/java/com | |
| parent | 880329e6b4ba209ea35ca647bb14157c1b4234fb (diff) | |
| download | Simple-3e17e811c4429cda194ccdb892ddb2bd10fa71ea.tar.gz Simple-3e17e811c4429cda194ccdb892ddb2bd10fa71ea.zip | |
Ch20 encoding (#177)
* ASM Printer
InstSel handles folding 2+ ideal ops into 1 machine op
* handle instSel for some control flow
Bool,If,CProj,Region,Phi
Handle 2-op expansions
Shuffle instSel graph walk back again.
* Basic if-block inst selects and asm prints
* Add mul-by-coinstant to shift
* left shift codegen basic
* exclude RSP from *write* mask
* 2-arg add (not immediate)
mul-by-small constant opt. Some utilities.
* Handle first loop
Change inst sel walk again to pre-order, to set an early visit bit to stop cycles.
CFGNode copies dom/loop info.
Cmp not-immediate form.
Ret/Fun lazy updates
* inst select for new struct allocation
* Float, bitwise and arithmetic operands codegen x86-64 (#150)
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* Remove non-exsting FP+imm ops
* Handle first loop
Change inst sel walk again to pre-order, to set an early visit bit to stop cycles.
CFGNode copies dom/loop info.
Cmp not-immediate form.
Ret/Fun lazy updates
* float ops without imm values
* merge
* merge
* inst select for new struct allocation
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* Remove non-exsting FP+imm ops
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* float ops without imm values
* merge
* merge
* Rebased on ch 19
* Update tests
---------
Co-authored-by: Cliff Click <cliffc@acm.org>
* cleanup after merge
alpha-sort helper fcns
implicit test vs zero/null
* Add LEA op
asm print works on ideal nodes for all tests
* Minor cleanup lea
* merge2
* merge3
* GCM for float ops fixed, other cleanup - small extensions
* x86 addressing modes during inst select
Drop New taking inits; just follow with initializing stores. Simplifies inst selelection which otherwise needs to undo this optimization and emit following init stores.
Basic load/store for now, op-to-mem comes later
add same becomes Shl by 1.
Drop DivF-immiedate
* call setup
* extended ch13, 14,15,16 (#153)
* merge2
* merge3
* Fix a few minor fuzzer bugs
* Force array layout
ld/st get size (but not signed/unsigned)
Add unsigned LT for later range checks.
* Fix a bunch of float issues
was deleting required inputs
* simpler invariant
defensive copy inputs for simpler invariant in complex sharing patterns
inc/dec form (just the opcode now).
* Call & CallR X86 instructions
* merge2
* Add-from-memory op
Remove FP immediate forms.
* Remove name from TFP
Never shoulda been there (but was convenient for awhile).
Moved into FunNode, found by checking the linker table with a TFP.
* remove debug prints
add check for bad call convention
fix 3 tests (bad merge?)
* cleanup call convention abi
Needs more love at some point...
* one more cleanup ABI
* New (#154)
* merge2
* merge3
* GCM for float ops fixed, other cleanup - small extensions
* call setup
* merge2
* remove debug prints
add check for bad call convention
fix 3 tests (bad merge?)
* cleanup call convention abi
Needs more love at some point...
* one more cleanup ABI
---------
Co-authored-by: Cliff Click <cliffc@acm.org>
* Add CmpMem form
Common addressing mode print
LEA can skip a base
* Add a AddFMemX86
A bunch of mem op patterns are missing, hopefully they are just cut-n-paste from the existing patterns.
* Docs
* XMM reg mask fix
Minor README updates
* Allow inverted cmp/mem
narrowing stores can bypass an AndMask
Array length loads do not need control
Some missing print info
* Support "*ptr op= val"
at least for MemAdd
* missed golden rule update
* Array len is u32
load-after-store zero/sign-extends if the store is truncating
* One more missed case
* READMEs
* Update README.md
* Update README.md
* Move printing into print dir
* Move codegen into codegen
* Framework for Reg Alloc
* riscv init
* added not imm form bitwise shifts and ops plus test cases
* addressing modes(high chance it'll get deleted)
* First cut BuildLRG
RegMask.EMPTY -> null
* fix minor bug
* Setup for first simple split
* First cut split code for mismatch regs
* delete non existing matches
* replace RegMask.Empty with null
* Live Ranges U-F
BuildLRG for Phi
Add CmpFX86
* FPR return
CallEndX86 needed to tell fp return from gpr ret
Call has no output regs.
* riscv handle store and load, fltRisch uses risc reg now
* load float into GPR and then later in RA do hard split.
* minor changes
* Next cut regalloc
Building IFG.
Coloring.
Some nested spilling
Optimize divf/con -> mul times inverse
* turn off ch20 tests
* Update Chapter20Test.java
* RISC-V basic isel (#156)
* Initial push
Major CodeGen cleanup; most static globals move into the CodeGen object.
* Minor progress bug with mutual recursion
* Add test from pr#148
* First cut x86 "port"
Only "return 0;", no registers, no encoding, but yah gotta start somewhere
* Update README.md
* Update README.md
* Update ListScheduler.java
* command line launcher for simple
Parser bug fref in args
Some new test cases.
* Add basic RegMask for more than 64 bits of register mask.
Add calling convention basics to X86; con+ret RegMasks.
GCM computes CFG for all users.
Drop unused MultiUse.
Pick up reg-pressure aware ListScheduler.
Re-layout CodeGen file to get code & data chunks nearer each other.
minor Ary extension
* ASM Printer
InstSel handles folding 2+ ideal ops into 1 machine op
* handle instSel for some control flow
Bool,If,CProj,Region,Phi
Handle 2-op expansions
Shuffle instSel graph walk back again.
* Basic if-block inst selects and asm prints
* Add mul-by-coinstant to shift
* left shift codegen basic
* exclude RSP from *write* mask
* 2-arg add (not immediate)
mul-by-small constant opt. Some utilities.
* Handle first loop
Change inst sel walk again to pre-order, to set an early visit bit to stop cycles.
CFGNode copies dom/loop info.
Cmp not-immediate form.
Ret/Fun lazy updates
* inst select for new struct allocation
* Float, bitwise and arithmetic operands codegen x86-64 (#150)
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* Remove non-exsting FP+imm ops
* Handle first loop
Change inst sel walk again to pre-order, to set an early visit bit to stop cycles.
CFGNode copies dom/loop info.
Cmp not-immediate form.
Ret/Fun lazy updates
* float ops without imm values
* merge
* merge
* inst select for new struct allocation
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* Remove non-exsting FP+imm ops
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* float ops without imm values
* merge
* merge
* Rebased on ch 19
* Update tests
---------
Co-authored-by: Cliff Click <cliffc@acm.org>
* cleanup after merge
alpha-sort helper fcns
implicit test vs zero/null
* Add LEA op
asm print works on ideal nodes for all tests
* Minor cleanup lea
* merge2
* merge3
* GCM for float ops fixed, other cleanup - small extensions
* x86 addressing modes during inst select
Drop New taking inits; just follow with initializing stores. Simplifies inst selelection which otherwise needs to undo this optimization and emit following init stores.
Basic load/store for now, op-to-mem comes later
add same becomes Shl by 1.
Drop DivF-immiedate
* call setup
* extended ch13, 14,15,16 (#153)
* merge2
* merge3
* Fix a few minor fuzzer bugs
* Force array layout
ld/st get size (but not signed/unsigned)
Add unsigned LT for later range checks.
* Fix a bunch of float issues
was deleting required inputs
* simpler invariant
defensive copy inputs for simpler invariant in complex sharing patterns
inc/dec form (just the opcode now).
* Call & CallR X86 instructions
* merge2
* Add-from-memory op
Remove FP immediate forms.
* Remove name from TFP
Never shoulda been there (but was convenient for awhile).
Moved into FunNode, found by checking the linker table with a TFP.
* remove debug prints
add check for bad call convention
fix 3 tests (bad merge?)
* cleanup call convention abi
Needs more love at some point...
* one more cleanup ABI
* New (#154)
* merge2
* merge3
* GCM for float ops fixed, other cleanup - small extensions
* call setup
* merge2
* remove debug prints
add check for bad call convention
fix 3 tests (bad merge?)
* cleanup call convention abi
Needs more love at some point...
* one more cleanup ABI
---------
Co-authored-by: Cliff Click <cliffc@acm.org>
* Add CmpMem form
Common addressing mode print
LEA can skip a base
* Add a AddFMemX86
A bunch of mem op patterns are missing, hopefully they are just cut-n-paste from the existing patterns.
* Docs
* XMM reg mask fix
Minor README updates
* Allow inverted cmp/mem
narrowing stores can bypass an AndMask
Array length loads do not need control
Some missing print info
* Support "*ptr op= val"
at least for MemAdd
* missed golden rule update
* Array len is u32
load-after-store zero/sign-extends if the store is truncating
* One more missed case
* riscv init
* added not imm form bitwise shifts and ops plus test cases
* addressing modes(high chance it'll get deleted)
* fix minor bug
* delete non existing matches
* replace RegMask.Empty with null
* riscv handle store and load, fltRisch uses risc reg now
* load float into GPR and then later in RA do hard split.
* minor changes
* turn off ch20 tests
* Update Chapter20Test.java
---------
Co-authored-by: Cliff Click <cliffc@acm.org>
* Bring pr/154 to ch 20
RISC5 changes.
Some missing x86 ops.
Still needs some calling convention love.
* First cut regalloc working
Biased coloring; tracking splits around a LRG.
Separate split for self-conflicts.
postColor to remove junk splits.
Some minor riscv fixes.
* Compile some riscv codes
If SplitEmptyMask does not apply, fall back to normal split.
Missing CmpFRISC.
Renamed riscv flags.
RetRISC handls FPR
remove extra RegMask constructurs
* add riscv port to readme
* arm init
* Progress reg alloc
Handle multi-node projections.
A little smarter about 2-addr scheduling
RegAlloc must-have single registers removes from other masks instead of interfering; had the mask removal backwards in a few cases.
LRG/RegMask COW expand masks before mutating.
Clone small constants instead of spilling.
Alloc & ProjX86 get output reg masks.
Full print large reg masks with sp+offset
* UF LRGs can be null during coloring
* Finish UF find
* work in progress
* README updates
* Fix ch19 mis-merge?
* x86 call args, risc5 load/store regs
* arm2 bs
* Push RISC WMASK
avoid writing to RSP
* work in progress
* clearnup arm
* Progress calling convention allocations
Call unlinks before reg alloc.
CallEnd tracks RPC
CallX86 requires TFP for correct ABI
Bias Color tracks 2-addr.
RPC gets a mask/stack-slot
Clean up call/fun ABI
Fix mask RET, RET_F
Fix print stack slot
Remove isMultiHead, isMultiTail
Better all-asm print
* Beef up Newton test
* fixed main pr problems
* regmask extra comments
* Clean pass normal tests
New fcn print upgrades several golden rule tests.
Move the unlink-all from the walk::err call (which IS used during IterPeeps) to GCM.
CallEnd upgrades return type based on constant call.
Fix unlink to also unlink CallEnd
Constant TFP print checks constant
Tested an untested Load
* Arm basics, minor changes in riscv (#160)
* Initial push
Major CodeGen cleanup; most static globals move into the CodeGen object.
* Minor progress bug with mutual recursion
* Add test from pr#148
* First cut x86 "port"
Only "return 0;", no registers, no encoding, but yah gotta start somewhere
* Update README.md
* Update README.md
* Update ListScheduler.java
* command line launcher for simple
Parser bug fref in args
Some new test cases.
* Add basic RegMask for more than 64 bits of register mask.
Add calling convention basics to X86; con+ret RegMasks.
GCM computes CFG for all users.
Drop unused MultiUse.
Pick up reg-pressure aware ListScheduler.
Re-layout CodeGen file to get code & data chunks nearer each other.
minor Ary extension
* ASM Printer
InstSel handles folding 2+ ideal ops into 1 machine op
* handle instSel for some control flow
Bool,If,CProj,Region,Phi
Handle 2-op expansions
Shuffle instSel graph walk back again.
* Basic if-block inst selects and asm prints
* Add mul-by-coinstant to shift
* left shift codegen basic
* exclude RSP from *write* mask
* 2-arg add (not immediate)
mul-by-small constant opt. Some utilities.
* Handle first loop
Change inst sel walk again to pre-order, to set an early visit bit to stop cycles.
CFGNode copies dom/loop info.
Cmp not-immediate form.
Ret/Fun lazy updates
* inst select for new struct allocation
* Float, bitwise and arithmetic operands codegen x86-64 (#150)
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* Remove non-exsting FP+imm ops
* Handle first loop
Change inst sel walk again to pre-order, to set an early visit bit to stop cycles.
CFGNode copies dom/loop info.
Cmp not-immediate form.
Ret/Fun lazy updates
* float ops without imm values
* merge
* merge
* inst select for new struct allocation
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* Remove non-exsting FP+imm ops
* left shift codegen basic
* sar codegen basic
* merge
* some basic ops
* addf
* divf, subf, mulf
* rsp allowed in bitwise input, not output
* formatting
* float ops without imm values
* merge
* merge
* Rebased on ch 19
* Update tests
---------
Co-authored-by: Cliff Click <cliffc@acm.org>
* cleanup after merge
alpha-sort helper fcns
implicit test vs zero/null
* Add LEA op
asm print works on ideal nodes for all tests
* Minor cleanup lea
* merge2
* merge3
* GCM for float ops fixed, other cleanup - small extensions
* x86 addressing modes during inst select
Drop New taking inits; just follow with initializing stores. Simplifies inst selelection which otherwise needs to undo this optimization and emit following init stores.
Basic load/store for now, op-to-mem comes later
add same becomes Shl by 1.
Drop DivF-immiedate
* call setup
* extended ch13, 14,15,16 (#153)
* merge2
* merge3
* Fix a few minor fuzzer bugs
* Force array layout
ld/st get size (but not signed/unsigned)
Add unsigned LT for later range checks.
* Fix a bunch of float issues
was deleting required inputs
* simpler invariant
defensive copy inputs for simpler invariant in complex sharing patterns
inc/dec form (just the opcode now).
* Call & CallR X86 instructions
* merge2
* Add-from-memory op
Remove FP immediate forms.
* Remove name from TFP
Never shoulda been there (but was convenient for awhile).
Moved into FunNode, found by checking the linker table with a TFP.
* remove debug prints
add check for bad call convention
fix 3 tests (bad merge?)
* cleanup call convention abi
Needs more love at some point...
* one more cleanup ABI
* New (#154)
* merge2
* merge3
* GCM for float ops fixed, other cleanup - small extensions
* call setup
* merge2
* remove debug prints
add check for bad call convention
fix 3 tests (bad merge?)
* cleanup call convention abi
Needs more love at some point...
* one more cleanup ABI
---------
Co-authored-by: Cliff Click <cliffc@acm.org>
* Add CmpMem form
Common addressing mode print
LEA can skip a base
* Add a AddFMemX86
A bunch of mem op patterns are missing, hopefully they are just cut-n-paste from the existing patterns.
* Docs
* XMM reg mask fix
Minor README updates
* Allow inverted cmp/mem
narrowing stores can bypass an AndMask
Array length loads do not need control
Some missing print info
* Support "*ptr op= val"
at least for MemAdd
* missed golden rule update
* Array len is u32
load-after-store zero/sign-extends if the store is truncating
* One more missed case
* riscv init
* added not imm form bitwise shifts and ops plus test cases
* addressing modes(high chance it'll get deleted)
* fix minor bug
* delete non existing matches
* replace RegMask.Empty with null
* riscv handle store and load, fltRisch uses risc reg now
* load float into GPR and then later in RA do hard split.
* minor changes
* turn off ch20 tests
* Update Chapter20Test.java
* add riscv port to readme
* arm init
* work in progress
* arm2 bs
* work in progress
* clearnup arm
* fixed main pr problems
* regmask extra comments
---------
Co-authored-by: Cliff Click <cliffc@acm.org>
* Update Chapter20Test.java
* Weaken range-check test
since no range checks... test cannot fail (pass)
* Fix issue #161
Error adding 'null' and '5'
* bug fixs, cloning constants
Fix bug missing Find.
Fix bug setDef does unordered removal from basic blocks.
Use cloned constants for spilling.
* RA fixes
SplitSelfConflict MUST split before uses and after defs.
Split global constants across functions
Missing find in union;
Inserting split after new inserted wrong place
Pre-remove null LRGs before color.
Bias color hunts through Phis
Shorten InstructionSelection.
Rename !unified() to leader()
AddMemX86 is 2-addr
Add CastXXX to preserve register across cast.
* encoding init
* encoding init 2
* rex fix
* indirect addressing modes
* setop change opcode, rename FLOAT_OFFSET
* mask sib and modrm with 3 bits, 4th bit goes into rex.
* sign extend div with cqo
* idiv input is fixed to rax and RMASK, grab input from second slot when encoding
* encoding of newx86
* tfp and CallEndNode encoding
* sib improvement
* more cleanups
* more cleanups
* Allow a killMap to kill regs.
Bugfix scheduler.
Bugfix spiller - self-conflict order depended on hashtable iteration order, which depended on System.hashCode which would vary run to run.
Improvements to coloring
Improvements to spill quality testing
* Added flags-kill for XOR
* Missing add-deps from fuzzer
* Update Chapter14Test.java
* fixed order of operands
* base rex fixup
* more bug fix
* remove jukn files
* minimal "make release"
* further fixes
* minor fixes
* minor fixes
* minor fixes
* base != -1 check, precedence fix
* Add regkills in IFG building
Fix bug LRG union stats
Adjust self-conflict splits to be slightly less aggressive
In every use-side split, dont split-after-split same block.
NewNode is a multi, does not define a register
* 64 bit encoding for gpr(s) load
* RA improvements
Attempt to commute to keep reg-masks compatible.
Clones with kills (x86 XOR killing flags to zero) fail before the flag-def.
Bugfix failed to color last lrg.
More smarts on picking trivial LRGs during coloring
Drop isSplit, add SplitNode
Pass regalloc round to all splits for debugging
Self-conflict no split on loop backedge.
Handle split that gets made goes dead
No-reg-mask spilling handles case with many def/uses.
Add DivIX86
BrainFuck, MergeSort now allocate as testing
* 8 bit imm support
* conditional jump fix
* Push l,ast change, unbreak branch
* XOR remove extra opcode, imm size supports 8 bit.
* Finally pass the `new [u8]` double-copy test
* Fix several ARM reg setup problems
Finish Split bypass check
ARM: rsp is also a fixed zero, in R31. R0 is a valid register.
CallArm prints args, passes TFP for arg selection. Does not return a register. All CallEndARM which DOES return a register. Parms missing tfp for float args. ProjARM after a New missing regs. RetARM missing RPC.
Remove hopeful DivIX86
* 64 bit imm for alu ops encoded in extra reg then use it in Op as an operand
* Bunch of minor arm, risc fixes
small constants not cloning
* jump invert encoding
* warning comment
* Much ARM fixage
One More Go-Round with Better Biased Colors
Fix bug picking deepest spills to bias.
ARM: remove default 2-address. Fix regmask overflow. Rename some ops to be canonical.
* Fixes to release
Port does not have to be in a Simple named directory.
Call convention is just a string, no enum
Missed some tests running RISC, ARM.
* Minor release change to allow another foreign port
* better split encoding and fix CallInMask
* notNode
* fix callInMask
* riscv init
* riscv basic ALU ops and types of instructions
* Allowing non-Simple repo ports
Expanding public API slightly so alternative (non-Simple repo) ports can happen.
RegMask supports single-bit-set and a long bitmask.
Bugfix GCM splitting multiple global constants.
Bugfix LCM grabbing a projection vs multi
Bugfix RegAlloc when avoiding splitting a clonable
Source code in release
More timing in CodeGen
* riscv indirect addressing and function calls
* Cleanup call ABI presentation
Everybody uses the same names, same code shapes
* Caller save regs
...not callee save yet
* Expose caller save regs
* Store Risc adjustments, no imm in MemOpRISC
* specific print encoding for cpus
* merge fixup
* More x86,risc,arm call convention fixes
Collect callee and caller save masks (inverts of each other, except for spills).
Reorg layout to be closer to each other; remove dead mask definitions; add final keyword
* lui fix up with 32 bit immediates
* Callee-save registers
Callee-save registers and masks and inserting LRGs for same and spilling and picking good spills. Insert CalleeSaveNodes and edges to RetXXXs and RegMasks for those edges.
Iterators for regmask.
Better printing post-allocation
* RegMask supports 128 bits
All regs available arm, risc.
MergeSort compiles & runs
* added flags splitting
* Fix risc5 compares
No flags on risc5.
Branch takes 2 inputs (one can be imm12).
Float compare only sets a GPR to 0/1.
Bool has a isFloat
Common risc5 imm-form handling
* extend test cases
* imm encoding, flags fixed
* grep for Todo: relocs
* float riscv fixed
* flags for set
* lui fix for small bits [0, 12]
* arm init
* arm last touches
* fmov still needs fix
* minor fixes
* minor fixes(2)
* got rid of unnecessary stuff
* create ch21
* remove encodings from chapter20 dir
* 1/2 pass cleaning up ARM encoding API
* ARM encoding compiles
* Risc R_TYPE and I_TYPE
* Progress RISC encodings
Missing lots of stuff still
* progress risc encoding
* risc encodings compile
* Update README.md
* Fold up redundant OP/OP-FP risc5 encoding
* x86 mem opcodes first cut
break out MemOp encodings into parts; change x86 indirectAdr to use Encoding class, remove redundant asserts & code
* x86 mem op encodings
* x86 reg+imm forms
* most reg-reg forms
* More x86 encodings
* Last few encodings
* switch to binary literals over decimals for opcodes
* logical immediates fixed, bitwise ops imm forms
* tfp and setArm fixed
* PC relative float for riscv
* readme init
* Merged pr/169
* Fixed the array1 test encodings
Clean up branch invert logic during BB layout
Cleanup branch target printing for RISC,ARM
ImmRISC ops mask imm12 to 12 bits
Fix NewRISC; hardcode RPC as part of call
Fix RISC inverting branchs >,>=
* floatarm encoding
* tfparm and intarm
* uncontional jump encoding for arm and riscv
* smarter IntARM, Intx86 does not always include rex.
* REX after PREFIX
* fixup load and store indirect
* updated rex prefix, if its 0x40 then its not needed
* Rex fix for floats, got rid of unnecessary stuff.
* rename to camel case, better param name
* add test export
* merged
* store opt
* store and load optimised forms handled
* tfp patch
* Store/load float arm/riscv/x64
* got rid of debug print
* splits for x86, riscv and arm
---------
Co-authored-by: Cliff Click <cliffc@acm.org>
Diffstat (limited to 'chapter21/src/main/java/com')
42 files changed, 180 insertions, 70 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java index fab40b1d..443320f0 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java @@ -17,7 +17,9 @@ public class AddIARM extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { return arm.RMASK; } @Override public RegMask outregmap() { return arm.RMASK; } //ADD (immediate) - @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b1001000100,_imm); } + @Override public void encoding( Encoding enc ) { + arm.imm_inst(enc,this,0b1001000100,_imm); + } // General form: "addi rd = rs1 + imm" @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + #").p(_imm); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java index ce270356..12d7d7c5 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java @@ -14,7 +14,9 @@ public class AndIARM extends MachConcreteNode implements MachNode { @Override public String op() { return "andi"; } @Override public RegMask regmap(int i) { return arm.RMASK; } @Override public RegMask outregmap() { return arm.RMASK; } - @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b100100100,_imm); } + @Override public void encoding( Encoding enc ) { + arm.imm_inst_n(enc,this,0b100100100,_imm); + } // General form: "andi rd = rs1 & imm" @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" & #").p(_imm); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java index e5636bc3..3371d3d2 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java @@ -22,7 +22,7 @@ public class AsrIARM extends MachConcreteNode implements MachNode { short rd = enc.reg(this); short rn = enc.reg(in(1)); assert _imm > 0; - enc.add4(arm.imm_shift(0b100100110,_imm, 0b111111, rn, rd)); + enc.add4(arm.imm_shift(0b1001001101,_imm, 0b111111, rn, rd)); } // General form: "asri rd = rs1 >> imm" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java index 800ad34c..1c3e2e49 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java @@ -4,6 +4,7 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.LoadNode; import com.seaofnodes.simple.node.Node; +import com.seaofnodes.simple.type.TypeFloat; // Load memory addressing on ARM // Support imm, reg(direct), or reg+off(indirect) addressing @@ -18,7 +19,13 @@ public class LoadARM extends MemOpARM{ @Override public String op() { return "ld"+_sz; } @Override public RegMask outregmap() { return arm.MEM_MASK; } // ldr(immediate - unsigned offset) | ldr(register) - @Override public void encoding( Encoding enc ) { ldst_encode(enc,0b11111000010,this); } + @Override public void encoding( Encoding enc ) { + if(_declaredType == TypeFloat.F32 || _declaredType == TypeFloat.F64) { + ldst_encode(enc, 0b1111110101, 0b11111100011, this, true); + } else { + ldst_encode(enc, 0b1111100101, 0b11111000011, this, false); + } + } @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(","); asm_address(code,sb); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java index d6633e51..3a7fc76c 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java @@ -24,7 +24,7 @@ public class LslIARM extends MachConcreteNode implements MachNode { assert _imm > 0; // UBFM <Xd>, <Xn>, #(-<shift> MOD 64), #(63-<shift>) // immr must be (-<shift> MOD 64) = 64 - shift - enc.add4(arm.imm_shift(0b110100110, 64 - _imm, (64 - _imm) - 1, rn, rd)); + enc.add4(arm.imm_shift(0b1101001101, 64 - _imm, (64 - _imm) - 1, rn, rd)); } // General form: "lsli rd = rs1 << imm" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java index 8bf2b9ce..7b9241d0 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java @@ -20,7 +20,7 @@ public class LsrIARM extends MachConcreteNode implements MachNode { short rd = enc.reg(this); short rn = enc.reg(in(1)); assert _imm > 0; - enc.add4(arm.imm_shift(0b110100110,_imm, 0b111111, rn,rd)); + enc.add4(arm.imm_shift(0b1101001101,_imm, 0b111111, rn,rd)); } // General form: "lsri rd = rs1 >>> imm" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java index 48e11522..ff3c41c3 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java @@ -47,14 +47,14 @@ public abstract class MemOpARM extends MemOpNode implements MachNode { throw Utils.TODO(); } - // Shared encoding for loads and stores - public void ldst_encode( Encoding enc, int opcode, Node xval ) { + // Shared encoding for loads and stores(int and float) + public void ldst_encode( Encoding enc, int opcode_imm, int opcode_reg, Node xval, boolean float_type ) { short ptr = enc.reg(ptr()); short off = enc.reg(off()); - short val = enc.reg(xval ); + short val = enc.reg(xval); int body = off() == null - ? arm.load_str_imm(opcode, off, ptr, val) - : arm.indr_adr(opcode+1, off, arm.STORE_LOAD_OPTION.SXTX, 0, ptr, val); + ? arm.load_str_imm(opcode_imm, _off, ptr, val) + : arm.indr_adr(opcode_reg, off, arm.STORE_LOAD_OPTION.SXTX, 0, ptr, val); enc.add4(body); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java index bb28acdb..afd44306 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java @@ -14,7 +14,9 @@ public class OrIARM extends MachConcreteNode implements MachNode { @Override public String op() { return "ori"; } @Override public RegMask regmap(int i) { return arm.RMASK; } @Override public RegMask outregmap() { return arm.RMASK; } - @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b101100100,_imm); } + @Override public void encoding( Encoding enc ) { + arm.imm_inst_n(enc, this, 0b101100100, _imm); + } // General form: "ori rd = rs1 | imm" @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" | #").p(_imm); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java index f3ef7f7b..b52533e0 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java @@ -1,8 +1,10 @@ package com.seaofnodes.simple.node.cpus.arm; +import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.Node; import com.seaofnodes.simple.node.SplitNode; +import com.seaofnodes.simple.node.cpus.riscv.riscv; public class SplitARM extends SplitNode { SplitARM(String kind, byte round) { super(kind,round,new Node[2]);} @@ -10,9 +12,43 @@ public class SplitARM extends SplitNode { @Override public RegMask outregmap() { return arm.SPLIT_MASK; } @Override public void encoding( Encoding enc ) { - short self = enc.reg(this ); - short reg1 = enc.reg(in(1)); - int body = arm.r_reg(0b10101010, 0, reg1, 0, 31, self); - enc.add4(body); + short dst = enc.reg(this ); + short src = enc.reg(in(1)); + + boolean dstX = dst >= arm.D_OFFSET; + boolean srcX = src >= arm.D_OFFSET; + + if (dst >= arm.MAX_REG) { + // store to sp + if(src >= arm.MAX_REG) { + throw Utils.TODO(); + } + int off = enc._fun.computeStackSlot(dst - arm.MAX_REG)*8; + enc.add4(arm.load_str_imm(0b1111100100, off, src, dst)); + } + + if(src >= arm.MAX_REG) { + // Load from SP + int off = enc._fun.computeStackSlot(src - arm.MAX_REG) * 8; + enc.add4(arm.load_str_imm(0b1111100101, off, src, dst)); + } + + // pick opcode based on regs + if(!dstX && !srcX) { + // GPR->GPR + enc.add4(arm.mov_reg(0b10101010000, src, dst)); + } else if(dstX && srcX) { + // FPR->FPR + // fmov reg + enc.add4(arm.f_mov_reg(0b00011110, src,dst)); + } else if(dstX && !srcX) { + // GPR->FPR + // FMOV(general) 64 bits to DOUBLE-PRECISION + enc.add4(arm.f_mov_general(0b10011110, 0b01, 0, 0b111, src, dst)); + } else if(!dstX && srcX) { + //FPF->GPR + // FMOV(general) DOUBLE-PRECISION to 64 bits + enc.add4(arm.f_mov_general(0b10011110, 0b01, 0, 0b110, src, dst)); + } } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java index e1fb592c..97ee6bb2 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java @@ -4,6 +4,7 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.StoreNode; import com.seaofnodes.simple.node.Node; +import com.seaofnodes.simple.type.TypeFloat; // Store memory addressing on ARM // Support imm, reg(direct), or reg+off(indirect) addressing @@ -21,7 +22,13 @@ public class StoreARM extends MemOpARM { } @Override public String op() { return "st"+_sz; } @Override public RegMask outregmap() { return null; } - @Override public void encoding( Encoding enc ) { ldst_encode(enc,0b11111000000, val()); } + @Override public void encoding( Encoding enc ) { + if(_declaredType == TypeFloat.F32 || _declaredType == TypeFloat.F64) { + ldst_encode(enc, 0b1111110100,0b11111100001, val(), true); + } else { + ldst_encode(enc, 0b1111100100, 0b11111000001, val(), false); + } + } @Override public void asm(CodeGen code, SB sb) { asm_address(code,sb).p(","); if( val()==null ) sb.p("#").p(_imm); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java index 4814a7cc..429cdb38 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java @@ -20,7 +20,7 @@ public class XorIARM extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return arm.RMASK; } // General form: "xori rd = rs1 ^ imm" - @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b110100100,_imm); } + @Override public void encoding( Encoding enc ) { arm.imm_inst_n(enc,this,0b110100100,_imm); } @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" ^ #").p(_imm); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java index 4b0781f2..4c3b3fc7 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java @@ -27,6 +27,7 @@ public class arm extends Machine { static final int D16 = 48, D17 = 49, D18 = 50, D19 = 51, D20 = 52, D21 = 53, D22 = 54, D23 = 55; static final int D24 = 56, D25 = 57, D26 = 58, D27 = 59, D28 = 60, D29 = 61, D30 = 62, D31 = 63; + static final int MAX_REG = 64; static final int D_OFFSET = 31; static final int FLAGS = 64; @@ -210,11 +211,11 @@ public class arm extends Machine { // sh is encoded in opcdoe public static int imm_inst(int opcode, int imm12, int rn, int rd) { assert opcode >=0 && imm12 >= 0 && rn >=0 && rd>=0; // Caller zeros high order bits - return (opcode << 23) | (imm12 << 10) | (rn << 5) | rd; + return (opcode << 22) | (imm12 << 10) | (rn << 5) | rd; } public static int imm_shift(int opcode, int imm, int imms, int rn, int rd) { - return (opcode << 23) | (1 << 22) | (imm << 16) | (imms << 10) | (rn << 5) | rd; + return (opcode << 22) | (1 << 22) | (imm << 16) | (imms << 10) | (rn << 5) | rd; } public static void imm_inst(Encoding enc, Node n, int opcode, int imm12) { @@ -224,6 +225,20 @@ public class arm extends Machine { enc.add4(body); } + public static void imm_inst_n(Encoding enc, Node n, int opcode, int imm13) { + short self = enc.reg(n); + short reg1 = enc.reg(n.in(1)); + + int body = imm_inst_n(opcode, imm13, reg1, self); + enc.add4(body); + } + + // nth bit comes from immediate and not opcode + public static int imm_inst_n(int opcode, int imm13, int rn, int rd) { + assert 0 <= imm13 && imm13 <= 0x1FFF; + return (opcode << 23) | (imm13 << 10) | (rn << 5) | rd; + } + public static int imm_inst_l(Encoding enc, Node n, int opcode, int imm12) { short self = enc.reg(n); short reg1 = enc.reg(n.in(1)); @@ -272,6 +287,10 @@ public class arm extends Machine { return (opcode << 23) | (shift << 21) | (imm16 << 5) | rd; } + public static int mov_reg(int opcode, int src, int dst) { + return (opcode << 21) | (src << 16) | 0b11111 << 5 | dst; + } + public static int ret(int opcode) { return (opcode << 10); } @@ -284,6 +303,13 @@ public class arm extends Machine { public static int f_scalar(int opcode, int ftype, int rm, int op, int rn, int rd) { return (opcode << 24) | (ftype << 22) | (1 << 21) | (rm << 16) | (op << 10) | (rn << 5) | rd; } + + public static int f_mov_reg(int opcode, int rn, int rd) { + return (opcode << 24) | (0b01100000010000 << 10) | (rn << 5) | rd; + } + public static int f_mov_general(int opcode, int ftype, int rmode, int opcode1, int rn, int rd) { + return (opcode << 24) |(ftype << 22) | (1 << 21) | (rmode << 19) | (opcode1 << 16) | (rn << 5) | rd; + } public static void f_scalar(Encoding enc, Node n, int op ) { short self = (short)(enc.reg(n) -D_OFFSET); short reg1 = (short)(enc.reg(n.in(1))-D_OFFSET); @@ -310,8 +336,8 @@ public class arm extends Machine { return (opcode << 21) | (off << 16) | (option.ordinal() << 13) | (s << 12) | (2 << 10) | (ptr << 5) | rt; } // [Rptr+imm9] - public static int load_str_imm(int opcode, int imm9, int ptr, int rt) { - return (opcode << 21) | (imm9 << 12) |(1 << 10) |(ptr << 5) | rt; + public static int load_str_imm(int opcode, int imm12, int ptr, int rt) { + return (opcode << 22) | (imm12 << 10) |(ptr << 5) | rt; } // encoding for vcvt, size is encoded in operand diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java index a1c23861..4d2ac916 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java @@ -4,13 +4,13 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; -// fadd.s +// fadd.d public class AddFRISC extends MachConcreteNode implements MachNode { AddFRISC(Node addf) {super(addf);} @Override public String op() { return "addf"; } @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } @Override public RegMask outregmap() { return riscv.FMASK; } - @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,0x53,riscv.RM.RNE,0); } + @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,1); } @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2))); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java index fa3c0249..c67d7b3d 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java @@ -4,13 +4,13 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; -// fdiv.s +// fdiv.d public class DivFRISC extends MachConcreteNode implements MachNode{ DivFRISC(Node divf) {super(divf);} @Override public String op() { return "divf"; } @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } @Override public RegMask outregmap() { return riscv.FMASK; } - @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,0x53,riscv.RM.RUP,0xC); } + @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RUP,13); } // Default on double precision for now(64 bits) // General form: "fdiv.d rd = src1 / src2 @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java index 12ffe364..a6f84c19 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java @@ -14,7 +14,7 @@ public class I2F8RISC extends MachConcreteNode implements MachNode { @Override public void encoding( Encoding enc ) { short dst = (short)(enc.reg(this )-riscv.F_OFFSET); short src1 = enc.reg(in(1)); - int body = riscv.r_type(riscv.OP_FP,dst,riscv.RM.RNE.ordinal(),src1,0,0x68); + int body = riscv.r_type(0b1010011,dst,riscv.RM.RNE.ordinal(),src1,0,0x69); enc.add4(body); } @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java index 6d7535e2..a3309038 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java @@ -17,7 +17,7 @@ public class LoadRISC extends MemOpRISC { @Override public void encoding( Encoding enc ) { short dst = xreg(enc); short ptr = enc.reg(ptr()); - int body = riscv.i_type(opcode(enc), dst, func3(), ptr, _off); + int body = riscv.i_type(opcode(enc), dst, func3(), ptr, _off); enc.add4(body); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java index acb7fbc1..1e19dfd4 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java @@ -38,13 +38,29 @@ public abstract class MemOpRISC extends MemOpNode implements MachNode { if( _declaredType == TypeInteger.BOOL) func3=4; // LBU if( _declaredType == TypeInteger.U16 ) func3=5; // LHU if( _declaredType == TypeInteger.U32 ) func3=6; // LWU + // float + if(_declaredType == TypeFloat.F32) func3 = 2; // fLW fSW + if(_declaredType == TypeFloat.F64) func3 = 3; // fLD fSD if( _declaredType instanceof TypeMemPtr ) func3=6; // 4 byte pointers, assumed unsigned? if( func3 == -1 ) throw Utils.TODO(); return func3; } // 7 bits, 00 000 11 or 00 001 11 for FP - int opcode(Encoding enc) { return enc.reg(this ) < riscv.F_OFFSET ? 3 : 7; } + int opcode(Encoding enc) { + if(enc.reg(this) < riscv.F_OFFSET) return 3; + else { + if(this instanceof LoadRISC) { + // opcode is same for 32 bit and 64 bits + return 7; + } + if(this instanceof StoreRISC) { + // opcode is the same for 32 bit and 64 bits + return 39; + } + } + return enc.reg(this ) < riscv.F_OFFSET ? 3 : 7; + } short xreg(Encoding enc) { short xreg = enc.reg(this ); return xreg < riscv.F_OFFSET ? xreg : (short)(xreg-riscv.F_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java index 1612854d..c9917b4f 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java @@ -4,13 +4,13 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; -// fmul.s +// fmul.d public class MulFRISC extends MachConcreteNode implements MachNode { MulFRISC(Node mulf) {super(mulf);} @Override public String op() { return "mulf"; } @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } @Override public RegMask outregmap() { return riscv.FMASK; } - @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,0x53,riscv.RM.RNE,0x9); } + @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,9); } @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" * ").p(code.reg(in(2))); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java index 7d43e1ec..7dbdf9bb 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java @@ -21,8 +21,9 @@ public class NewRISC extends NewNode implements MachNode { // Generic external encoding; 2 ops. enc.external(this,"calloc"); // A1 is a caller-save, allowed to crush building external address + // auipc enc.add4(riscv.u_type(0x17, riscv.A1, 0)); - enc.add4(riscv.i_type(0x67, riscv.RPC, riscv.I_JALR, riscv.A1, 0)); + enc.add4(riscv.i_type(0x67, riscv.RPC, 0, riscv.A1, 0)); } // General form: "alloc #bytes PC" diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java index c6a31bdb..a322e8e4 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java @@ -19,15 +19,18 @@ public class SplitRISC extends SplitNode { if( dst >= riscv.MAX_REG ) { // Store to SP - if( src >= riscv.MAX_REG ) + if( src >= riscv.MAX_REG ) { throw Utils.TODO(); // Very rare stack-stack move + } + int off = enc._fun.computeStackSlot(dst - riscv.MAX_REG)*8; - throw Utils.TODO(); + // store 64 bit values + enc.add4(riscv.s_type(39, 3, riscv.SP, dst, off)); } if( src >= riscv.MAX_REG ) { // Load from SP int off = enc._fun.computeStackSlot(src - riscv.MAX_REG)*8; - throw Utils.TODO(); + enc.add4(riscv.i_type(7, dst, 3,riscv.SP, off)); } // pick opcode based on regs if( !dstX && !srcX ) { @@ -35,13 +38,17 @@ public class SplitRISC extends SplitNode { enc.add4(riscv.r_type(riscv.OP,dst,0,src,riscv.ZERO,0)); } else if( dstX && srcX ) { // FPR->FPR - throw Utils.TODO(); + // Can do: FPR->GPR->FPR + enc.add4(riscv.r_type(0b1010011, dst, 0, src, 0, 0b1110001)); + enc.add4(riscv.r_type(0b1010011, dst, 0, src, 0, 0b0100000)); } else if( dstX && !srcX ) { //GPR->FPR - throw Utils.TODO(); + // fmv.d.x + enc.add4(riscv.r_type(0b1010011, dst, 0, src, 0, 0b0100000)); } else if( !dstX && srcX ) { //FPR->GPR - throw Utils.TODO(); + //fmv.x.d + enc.add4(riscv.r_type(0b1010011, dst, 0, src, 0, 0b1110001)); } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java index 11ff42a7..b97117d5 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java @@ -34,7 +34,7 @@ public class StoreRISC extends MemOpRISC { @Override public void encoding( Encoding enc ) { short val = xreg(enc); short ptr = enc.reg(ptr()); - int body = riscv.s_type(opcode(enc), ptr, func3()&3, val, _off); + int body = riscv.s_type(opcode(enc), func3()&3, ptr, val, _off); enc.add4(body); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java index c59a70b4..1e1b43c7 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java @@ -4,13 +4,13 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; -// fsub.s +// fsub.d public class SubFRISC extends MachConcreteNode implements MachNode { SubFRISC(Node subf) {super(subf);} @Override public String op() { return "subf"; } @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } @Override public RegMask outregmap() { return riscv.FMASK; } - @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,0x53,riscv.RM.RNE,0x5); } + @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,5); } @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2))); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java index 4e223f73..9bf560cf 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java @@ -106,13 +106,12 @@ public class riscv extends Machine { // // major opcode: OP public static int OP = 0b01_100_11; - public static int OP_FP = 0b11_100_11; + public static int OP_FP = 0b10_100_11; //I_type opcode: 0010 0011 public static int I_TYPE = 0x13; // 0110 0111 - public static int I_JALR = 0x67; public static int J_JAL = 0b1101111; @@ -127,7 +126,7 @@ public class riscv extends Machine { int body = r_type(OP,dst,func3,src1,src2,func7); enc.add4(body); } - public static void rf_type(Encoding enc, Node n, int opcode, RM func3, int func7) { + public static void rf_type(Encoding enc, Node n, RM func3, int func7) { short dst = (short)(enc.reg(n )-F_OFFSET); short src1 = (short)(enc.reg(n.in(1))-F_OFFSET); short src2 = (short)(enc.reg(n.in(2))-F_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java index 720be638..a4166bc7 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java @@ -12,7 +12,6 @@ public class AddFX86 extends MachConcreteNode implements MachNode { @Override public int twoAddress() { return 1; } @Override public boolean commutes() { return true; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // F2 0F 58 /r ADDSD xmm1, xmm2/m64 short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java index fc1da246..f4e243bc 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java @@ -24,7 +24,6 @@ public class CallX86 extends CallNode implements MachNode, RIPRelSize { @Override public RegMask outregmap() { return null; } @Override public int nargs() { return nIns()-2; } // Minus control, memory, fptr - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { enc.relo(this).add1(0xe8).add4(0); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java index c2d0ff0f..35b92170 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java @@ -10,7 +10,6 @@ public class CmpFX86 extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { return x86_64_v2.XMASK; } @Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // UCOMISD short src1 = (short)(enc.reg(in(1)) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java index ccb79710..6271afcd 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java @@ -29,7 +29,7 @@ public class CmpIX86 extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; } @Override public boolean isClone() { return true; } @Override public Node copy() { return new CmpIX86(this); } - // Encoding is appended into the byte array; size is returned + @Override public final void encoding( Encoding enc ) { short dst = enc.reg(this); // Also src1 enc.add1(x86_64_v2.rex(0, dst, 0)); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java index cc89e808..9509a1f5 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java @@ -11,7 +11,6 @@ public class DivFX86 extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return x86_64_v2.XMASK; } @Override public int twoAddress() { return 1; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // F2 0F 5E /r DIVSD xmm1, xmm2/m64 short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java index 307d745f..708269bd 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java @@ -13,7 +13,6 @@ public class FltX86 extends ConstantNode implements MachNode, RIPRelSize { @Override public boolean isClone() { return true; } @Override public Node copy() { return new FltX86(this); } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // Load the constant into a FPR // movsd xmm, [rip + 0] diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java index ef821e83..d3213ae4 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java @@ -10,7 +10,6 @@ public class I2f8X86 extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { assert i==1; return x86_64_v2.WMASK; } @Override public RegMask outregmap() { return x86_64_v2.XMASK; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // F2 0F 2A /r CVTSI2SD xmm1, r32/m32 short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java index e3285d55..760d6805 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java @@ -19,7 +19,6 @@ public abstract class ImmX86 extends MachConcreteNode implements MachNode { abstract int opcode(); abstract int mod(); - // Encoding is appended into the byte array; size is returned @Override public final void encoding( Encoding enc ) { short dst = enc.reg(this); // Also src1 enc.add1(x86_64_v2.rex(0, dst, 0)); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java index 876660aa..10b111e4 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java @@ -27,7 +27,6 @@ public class JmpX86 extends IfNode implements MachNode, RIPRelSize { @Override public RegMask outregmap() { return null; } @Override public void invert() { _bop = invert(_bop); } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { enc.jump(this,cproj(0)); int op = x86_64_v2.jumpop(_bop); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java index cdae9f93..dce8a49a 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java @@ -22,7 +22,6 @@ public class LeaX86 extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { assert i==1 || i==2; return x86_64_v2.RMASK; } @Override public RegMask outregmap() { return x86_64_v2.WMASK; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // REX.W + 8D /r LEA r64,m short dst = enc.reg(this); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java index 6dd3e3dc..16f36173 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java @@ -5,6 +5,7 @@ import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.LoadNode; import com.seaofnodes.simple.node.Node; import com.seaofnodes.simple.type.Type; +import com.seaofnodes.simple.type.TypeFloat; import com.seaofnodes.simple.type.TypeInteger; public class LoadX86 extends MemOpX86 { @@ -21,10 +22,25 @@ public class LoadX86 extends MemOpX86 { short dst = enc.reg(this ); short ptr = enc.reg(ptr()); short idx = enc.reg(idx()); - if (_declaredType != TypeInteger.U32) { + + if (_declaredType != TypeInteger.U32 && _declaredType != TypeFloat.F32 && _declaredType != TypeFloat.F64) { enc.add1(x86_64_v2.rex(dst, ptr, idx)); } + if(_declaredType == TypeFloat.F32) { + // F3 0F 10 /r MOVSS xmm1, m32 + enc.add1(0xF3); + enc.add1(0x0F); + enc.add1(0x10); + dst -= (short)x86_64_v2.XMM_OFFSET; + } + if(_declaredType == TypeFloat.F64) { + // F2 0F 10 /r MOVSD xmm1, m64 + enc.add1(0xF2); + enc.add1(0x0F); + enc.add1(0x10); + dst -= (short)x86_64_v2.XMM_OFFSET; + } if(_declaredType == TypeInteger.I8) { // sign extend: REX.W + 0F BE /r MOVSX r64, r/m8 enc.add1(0x0F); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java index 0af87037..c1edb082 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java @@ -12,7 +12,6 @@ public class MulFX86 extends MachConcreteNode implements MachNode { @Override public int twoAddress() { return 1; } @Override public boolean commutes() { return true; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // F2 0F 59 /r MULSD xmm1,xmm2/m64 short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java index 8800f159..3cd1f795 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java @@ -12,7 +12,6 @@ public class MulX86 extends MachConcreteNode implements MachNode { @Override public int twoAddress() { return 1; } @Override public boolean commutes() { return true; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // REX.W + 0F AF /r IMUL r64, r/m64 short dst = enc.reg(this ); // src1 diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java index 6263213d..456d0093 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java @@ -15,7 +15,6 @@ public class NewX86 extends NewNode implements MachNode { @Override public RegMask outregmap() { return null; } @Override public RegMask killmap() { return x86_64_v2.x86CallerSave(); } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { enc.external(this,"calloc"); // E8 cd CALL rel32; diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java index 1d8fa127..36e32bb8 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java @@ -20,7 +20,6 @@ public class SetX86 extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { assert i==1; return x86_64_v2.FLAGS_MASK; } @Override public RegMask outregmap() { return x86_64_v2.WMASK; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // REX + 0F 94 short dst = enc.reg(this ); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java index 15657de0..a718ee51 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java @@ -14,7 +14,6 @@ public class SplitX86 extends SplitNode { // Need to handle 8 cases: . reg->reg, reg->xmm, reg->flags, xmm->reg, xmm->xmm, xmm->flags, flags->reg, flags->xmm, // flags->flags. - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // REX.W + 8B /r MOV r64, r/m64 short dst = enc.reg(this ); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java index 8c2e0612..9a5d7925 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java @@ -5,6 +5,8 @@ import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; import com.seaofnodes.simple.node.Node; import com.seaofnodes.simple.node.StoreNode; +import com.seaofnodes.simple.type.TypeFloat; + import java.util.BitSet; public class StoreX86 extends MemOpX86 { @@ -33,11 +35,12 @@ public class StoreX86 extends MemOpX86 { if(imm_op == -1) {enc.add1(x86_64_v2.rex(src, ptr, idx));enc.add1(0xC7); } else enc.add1(imm_op); } else { - - if(_declaredType.log_size() == 0) enc.add1(0x88); - if(_declaredType.log_size() == 1) enc.add1(0x89); - if(_declaredType.log_size() == 2) enc.add1(0x89); - if(_declaredType.log_size() == 3) {enc.add1(x86_64_v2.rex(src, ptr, idx)); enc.add1(0x89);} + if(_declaredType == TypeFloat.F32) {src -= (short)x86_64_v2.XMM_OFFSET; enc.add1(0xF3); enc.add1(0x0F); enc.add1(0x11);} + else if(_declaredType == TypeFloat.F64) {src -= (short)x86_64_v2.XMM_OFFSET; enc.add1(0xF2); enc.add1(0x0F); enc.add1(0x11);} + else if(_declaredType.log_size() == 0) enc.add1(0x88); + else if(_declaredType.log_size() == 1) enc.add1(0x89); + else if(_declaredType.log_size() == 2) enc.add1(0x89); + else if(_declaredType.log_size() == 3) {enc.add1(x86_64_v2.rex(src, ptr, idx)); enc.add1(0x89);} } x86_64_v2.indirectAdr(_scale, idx, ptr, _off, src, enc); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java index 07084932..0a169a22 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java @@ -11,7 +11,6 @@ public class SubFX86 extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return x86_64_v2.XMASK; } @Override public int twoAddress() { return 1; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // F2 0F 5C /r SUBSD xmm1, xmm2/m64 short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java index 01b878a0..f51e0c75 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java @@ -434,8 +434,9 @@ public class x86_64_v2 extends Machine { if( lhs instanceof LoadNode ld && ld.nOuts() == 1 && ld._declaredType.log_size() >= 3) return new AddMemX86(add, address(ld), ld.ptr(), idx, off, scale, imm(rhs), val); - if(rhs instanceof LoadNode ld && ld.nOuts() == 1 && ld._declaredType.log_size() >= 3) - throw Utils.TODO(); // Swap load sides +// if(rhs instanceof LoadNode ld && ld.nOuts() == 1 && ld._declaredType.log_size() >= 3) { +// throw Utils.TODO(); // Swap load sides +// } // Attempt a full LEA-style break down. // Returns one of AddX86, AddIX86, LeaX86, or LHS @@ -463,8 +464,8 @@ public class x86_64_v2 extends Machine { if(addf.in(1) instanceof LoadNode ld && ld.nOuts() == 1) return new AddFMemX86(addf, address(ld), ld.ptr(), idx, off, scale, addf.in(2)); - if(addf.in(2) instanceof LoadNode ld && ld.nOuts() == 1) - throw Utils.TODO(); // Swap load sides +// if(addf.in(2) instanceof LoadNode ld && ld.nOuts() == 1) +// throw Utils.TODO(); // Swap load sides return new AddFX86(addf); } |
