├── lexer ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── compilerprogramming │ └── ezlang │ └── lexer │ └── Token.java ├── parser ├── README.md ├── pom.xml └── src │ └── test │ └── java │ └── com │ └── compilerprogramming │ └── ezlang │ └── parser │ └── TestParser.java ├── seaofnodes ├── src │ ├── test │ │ ├── cases │ │ │ ├── hello │ │ │ │ └── hello.ez │ │ │ ├── sieve │ │ │ │ ├── README.md │ │ │ │ ├── sieve.smp │ │ │ │ └── sieve.ez │ │ │ ├── fib │ │ │ │ ├── README.md │ │ │ │ ├── fib.smp │ │ │ │ ├── fib.ez │ │ │ │ ├── fib.ez_out │ │ │ │ └── fib.smp_out │ │ │ └── mergsort │ │ │ │ └── README.md │ │ └── java │ │ │ └── com │ │ │ └── compilerprogramming │ │ │ └── ezlang │ │ │ └── compiler │ │ │ └── Main.java │ └── main │ │ └── java │ │ └── com │ │ └── compilerprogramming │ │ └── ezlang │ │ └── compiler │ │ ├── node │ │ ├── cpus │ │ │ ├── x86_64_v2 │ │ │ │ ├── SubX86.java │ │ │ │ ├── OrIX86.java │ │ │ │ ├── AndIX86.java │ │ │ │ ├── OrX86.java │ │ │ │ ├── XorIX86.java │ │ │ │ ├── AddX86.java │ │ │ │ ├── AndX86.java │ │ │ │ ├── XorX86.java │ │ │ │ ├── ProjX86.java │ │ │ │ ├── ParmX86.java │ │ │ │ ├── RetX86.java │ │ │ │ ├── NewX86.java │ │ │ │ ├── AddIX86.java │ │ │ │ ├── SarX86.java │ │ │ │ ├── ShlX86.java │ │ │ │ ├── ShrX86.java │ │ │ │ ├── NegX86.java │ │ │ │ ├── RegX86.java │ │ │ │ ├── I2f8X86.java │ │ │ │ ├── MulX86.java │ │ │ │ ├── DivFX86.java │ │ │ │ ├── CmpFX86.java │ │ │ │ ├── SubFX86.java │ │ │ │ ├── AddMemX86.java │ │ │ │ ├── CallRX86.java │ │ │ │ ├── MulFX86.java │ │ │ │ ├── AddFX86.java │ │ │ │ ├── FunX86.java │ │ │ │ ├── DivX86.java │ │ │ │ ├── CmpX86.java │ │ │ │ ├── ShrIX86.java │ │ │ │ ├── ImmX86.java │ │ │ │ ├── ShlIX86.java │ │ │ │ ├── MemAddX86.java │ │ │ │ ├── SarIX86.java │ │ │ │ ├── TMPX86.java │ │ │ │ └── NotX86.java │ │ │ ├── riscv │ │ │ │ ├── AndIRISC.java │ │ │ │ ├── OrIRISC.java │ │ │ │ ├── SllIRISC.java │ │ │ │ ├── SrlIRISC.java │ │ │ │ ├── SraIRISC.java │ │ │ │ ├── XorIRISC.java │ │ │ │ ├── ProjRISC.java │ │ │ │ ├── SetIRISC.java │ │ │ │ ├── ParmRISC.java │ │ │ │ ├── OrRISC.java │ │ │ │ ├── XorRISC.java │ │ │ │ ├── AndRISC.java │ │ │ │ ├── DivRISC.java │ │ │ │ ├── SubRISC.java │ │ │ │ ├── SllRISC.java │ │ │ │ ├── SrlRISC.java │ │ │ │ ├── AddFRISC.java │ │ │ │ ├── MulFRISC.java │ │ │ │ ├── SraRISC.java │ │ │ │ ├── SubFRISC.java │ │ │ │ ├── MulRISC.java │ │ │ │ ├── NegRISC.java │ │ │ │ ├── RetRISC.java │ │ │ │ ├── AddIRISC.java │ │ │ │ ├── AddRISC.java │ │ │ │ ├── DivFRISC.java │ │ │ │ ├── SetRISC.java │ │ │ │ ├── FunRISC.java │ │ │ │ ├── NotRISC.java │ │ │ │ ├── I2F8RISC.java │ │ │ │ ├── CallRRISC.java │ │ │ │ ├── LoadRISC.java │ │ │ │ ├── LUI.java │ │ │ │ ├── SetFRISC.java │ │ │ │ └── IntRISC.java │ │ │ └── arm │ │ │ │ ├── RetARM.java │ │ │ │ ├── ProjARM.java │ │ │ │ ├── ParmARM.java │ │ │ │ ├── AsrARM.java │ │ │ │ ├── LslARM.java │ │ │ │ ├── LsrARM.java │ │ │ │ ├── SubARM.java │ │ │ │ ├── DivARM.java │ │ │ │ ├── AddARM.java │ │ │ │ ├── DivFARM.java │ │ │ │ ├── MulARM.java │ │ │ │ ├── XorARM.java │ │ │ │ ├── MulFARM.java │ │ │ │ ├── SubFARM.java │ │ │ │ ├── OrARM.java │ │ │ │ ├── AddFARM.java │ │ │ │ ├── CmpARM.java │ │ │ │ ├── CmpFARM.java │ │ │ │ ├── FunARM.java │ │ │ │ ├── OrIARM.java │ │ │ │ ├── AndIARM.java │ │ │ │ ├── NegARM.java │ │ │ │ ├── I2F8ARM.java │ │ │ │ ├── AndARM.java │ │ │ │ ├── AddIARM.java │ │ │ │ ├── SubIARM.java │ │ │ │ ├── XorIARM.java │ │ │ │ ├── LsrIARM.java │ │ │ │ ├── CallRRARM.java │ │ │ │ ├── SetARM.java │ │ │ │ ├── NotARM.java │ │ │ │ ├── AsrIARM.java │ │ │ │ ├── NewARM.java │ │ │ │ ├── LslIARM.java │ │ │ │ ├── CmpIARM.java │ │ │ │ └── LoadARM.java │ │ ├── CtrlNode.java │ │ ├── XCtrlNode.java │ │ ├── NeverNode.java │ │ ├── ExternNode.java │ │ ├── CastMach.java │ │ ├── DivNode.java │ │ ├── MultiNode.java │ │ ├── ReadOnlyMach.java │ │ ├── CalleeSaveNode.java │ │ ├── ReadOnlyNode.java │ │ ├── MinusFNode.java │ │ ├── NotNode.java │ │ ├── MachConcreteNode.java │ │ ├── RoundF32Node.java │ │ ├── SplitNode.java │ │ ├── ShrNode.java │ │ ├── ToFloatNode.java │ │ ├── MinusNode.java │ │ ├── SarNode.java │ │ ├── FRefNode.java │ │ ├── AddFNode.java │ │ ├── DivFNode.java │ │ ├── SubFNode.java │ │ ├── SubNode.java │ │ ├── StructNode.java │ │ ├── OrNode.java │ │ ├── CallEndMach.java │ │ ├── XorNode.java │ │ ├── ParmNode.java │ │ └── MulFNode.java │ │ ├── codegen │ │ ├── LinkMem.java │ │ ├── RIPRelSize.java │ │ └── RegMaskRW.java │ │ ├── Var.java │ │ └── util │ │ └── Utils.java ├── README.md └── pom.xml ├── types ├── README.md ├── src │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── compilerprogramming │ │ │ └── ezlang │ │ │ └── types │ │ │ └── TestTypes.java │ └── main │ │ └── java │ │ └── com │ │ └── compilerprogramming │ │ └── ezlang │ │ └── types │ │ ├── Scope.java │ │ └── Symbol.java └── pom.xml ├── semantic ├── README.md └── pom.xml ├── stackvm ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── compilerprogramming │ └── ezlang │ └── compiler │ └── BasicBlock.java ├── antlr-parser ├── README.md └── examples │ └── all-features.lang ├── registervm ├── README.md ├── src │ └── main │ │ └── java │ │ └── com │ │ └── compilerprogramming │ │ └── ezlang │ │ ├── interpreter │ │ ├── ExecutionStack.java │ │ └── Value.java │ │ └── compiler │ │ └── BasicBlock.java └── pom.xml ├── optvm ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── compilerprogramming │ │ │ └── ezlang │ │ │ ├── interpreter │ │ │ ├── ExecutionStack.java │ │ │ └── Value.java │ │ │ └── compiler │ │ │ ├── ExitSSA.java │ │ │ ├── Optimizer.java │ │ │ ├── LiveSet.java │ │ │ └── Options.java │ └── test │ │ └── java │ │ └── com │ │ └── compilerprogramming │ │ └── ezlang │ │ └── compiler │ │ └── TestChaitinRegAllocator.java └── pom.xml ├── common ├── src │ └── main │ │ └── java │ │ └── com │ │ └── compilerprogramming │ │ └── ezlang │ │ └── exceptions │ │ ├── InterpreterException.java │ │ └── CompilerException.java └── pom.xml ├── .gitignore └── .github └── workflows └── maven.yml /lexer/README.md: -------------------------------------------------------------------------------- 1 | # Lexer 2 | 3 | For now please checkout the code. Docs to follow. -------------------------------------------------------------------------------- /parser/README.md: -------------------------------------------------------------------------------- 1 | # Parser 2 | 3 | For now please checkout the code. Docs to follow. 4 | -------------------------------------------------------------------------------- /seaofnodes/src/test/cases/hello/hello.ez: -------------------------------------------------------------------------------- 1 | func main()->Int 2 | { 3 | return 1 4 | } -------------------------------------------------------------------------------- /types/README.md: -------------------------------------------------------------------------------- 1 | # Type System 2 | 3 | For now please checkout the code. Docs to follow. -------------------------------------------------------------------------------- /semantic/README.md: -------------------------------------------------------------------------------- 1 | # Semantic Analyzer 2 | 3 | For now please checkout the code. Docs to follow. -------------------------------------------------------------------------------- /stackvm/README.md: -------------------------------------------------------------------------------- 1 | # Intermediate Representation using Stack 2 | 3 | Implements a compiler that generates IR for an abstract machine that uses a stack based execution model. -------------------------------------------------------------------------------- /antlr-parser/README.md: -------------------------------------------------------------------------------- 1 | # EZ Programming Language 2 | 3 | Provides an ANTLR version of the grammar. Note that the actual parser implements a hand coded recursive descent parser. -------------------------------------------------------------------------------- /seaofnodes/src/test/cases/sieve/README.md: -------------------------------------------------------------------------------- 1 | ### Notes 2 | 3 | Flags used: 4 | 5 | ``` 6 | --dump-after-local-sched -S --cpu x86_64_v2 --abi SystemV 7 | ``` 8 | 9 | Outputs from Simple ch22 and EZ -------------------------------------------------------------------------------- /seaofnodes/src/test/cases/fib/README.md: -------------------------------------------------------------------------------- 1 | ### Notes 2 | 3 | Flags being used: 4 | 5 | ``` 6 | --dump-after-local-sched -S --cpu x86_64_v2 --abi SystemV 7 | ``` 8 | 9 | Simple ch21 output because fails in ch22. -------------------------------------------------------------------------------- /seaofnodes/README.md: -------------------------------------------------------------------------------- 1 | ## Sea of Nodes IR 2 | 3 | This module uses the [Simple](https://github.com/SeaOfNodes/Simple) project as a Sea of Nodes 4 | backend. We translate from the EeZee AST to Sea of Nodes IR. 5 | 6 | For copyright info on Simple project please see above website. -------------------------------------------------------------------------------- /registervm/README.md: -------------------------------------------------------------------------------- 1 | # Intermediate Representation using Three Address Instructions 2 | 3 | Well, its not always three address instructions but the main idea is that instructions directly 4 | address locations called Virtual Registers. 5 | 6 | For now please checkout the code. Docs to follow. -------------------------------------------------------------------------------- /seaofnodes/src/test/cases/fib/fib.smp: -------------------------------------------------------------------------------- 1 | val fib = {int n -> 2 | int temp=0; 3 | int f1=1; 4 | int f2=1; 5 | int i=n; 6 | while( i>1 ){ 7 | temp = f1+f2; 8 | f1=f2; 9 | f2=temp; 10 | i=i-1; 11 | } 12 | return f2; 13 | }; 14 | 15 | fib(10); -------------------------------------------------------------------------------- /seaofnodes/src/test/cases/fib/fib.ez: -------------------------------------------------------------------------------- 1 | func fib(n: Int)->Int { 2 | var f1=1 3 | var f2=1 4 | var i=n 5 | while( i>1 ){ 6 | var temp = f1+f2 7 | f1=f2 8 | f2=temp 9 | i=i-1 10 | } 11 | return f2 12 | } 13 | 14 | func foo()->Int { 15 | return fib(10) 16 | } -------------------------------------------------------------------------------- /seaofnodes/src/test/cases/mergsort/README.md: -------------------------------------------------------------------------------- 1 | ### simple 2 | 3 | To compare 4 | 5 | Turn off inlining in CallEndNode 6 | 7 | Run simple on our test 8 | 9 | --dump-after-local-sched -S --cpu x86_64_v2 --abi Win64 /pat/to/file.smp 10 | 11 | Then run the same test in EZ 12 | 13 | --dump-after-local-sched -S --cpu x86_64_v2 --abi Win64 /pat/to/file.ez 14 | 15 | -------------------------------------------------------------------------------- /optvm/src/main/java/com/compilerprogramming/ezlang/interpreter/ExecutionStack.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.interpreter; 2 | 3 | public class ExecutionStack { 4 | 5 | public Value[] stack; 6 | public int sp; 7 | 8 | public ExecutionStack(int maxStackSize) { 9 | this.stack = new Value[maxStackSize]; 10 | this.sp = -1; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /registervm/src/main/java/com/compilerprogramming/ezlang/interpreter/ExecutionStack.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.interpreter; 2 | 3 | public class ExecutionStack { 4 | 5 | public Value[] stack; 6 | public int sp; 7 | 8 | public ExecutionStack(int maxStackSize) { 9 | this.stack = new Value[maxStackSize]; 10 | this.sp = -1; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/src/main/java/com/compilerprogramming/ezlang/exceptions/InterpreterException.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.exceptions; 2 | 3 | public class InterpreterException extends RuntimeException { 4 | public InterpreterException(String message) {super(message);} 5 | public InterpreterException(String message, Throwable cause) { 6 | super(message, cause); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | replay_pid* 25 | 26 | .idea 27 | 28 | target -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/SubX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class SubX86 extends RegX86 { 6 | SubX86( Node add ) { super(add); } 7 | @Override public String op() { return "sub"; } 8 | @Override public String glabel() { return "-"; } 9 | @Override int opcode() { return 0x2B; } 10 | } 11 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/OrIX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class OrIX86 extends ImmX86 { 6 | OrIX86( Node add, int imm ) { super(add,imm); } 7 | @Override public String op() { return "ori"; } 8 | @Override public String glabel() { return "|"; } 9 | @Override int opcode() { return 0x81; } 10 | @Override int mod() { return 1; } 11 | } 12 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/AndIX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class AndIX86 extends ImmX86 { 6 | AndIX86( Node add, int imm ) { super(add,imm); } 7 | @Override public String op() { return "andi"; } 8 | @Override public String glabel() { return "&"; } 9 | @Override int opcode() { return 0x81; } 10 | @Override int mod() { return 4; } 11 | } 12 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/OrX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class OrX86 extends RegX86 { 6 | OrX86( Node add ) { super(add); } 7 | @Override public String op() { return "or"; } 8 | @Override public String glabel() { return "|"; } 9 | @Override int opcode() { return 0x0B; } 10 | @Override public boolean commutes() { return true; } 11 | } 12 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/XorIX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class XorIX86 extends ImmX86 { 6 | XorIX86( Node add, int imm ) { super(add,imm); } 7 | @Override public String op() { return "xori"; } 8 | @Override public String glabel() { return "^"; } 9 | @Override int opcode() { return 0x81; } 10 | @Override int mod() { return 6; } 11 | } 12 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/AddX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class AddX86 extends RegX86 { 6 | AddX86( Node add ) { super(add); } 7 | @Override public String op() { return "add"; } 8 | @Override public String glabel() { return "+"; } 9 | @Override int opcode() { return 0x03; } 10 | @Override public boolean commutes() { return true; } 11 | } 12 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/AndX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class AndX86 extends RegX86 { 6 | AndX86( Node add ) { super(add); } 7 | @Override public String op() { return "and"; } 8 | @Override public String glabel() { return "&"; } 9 | @Override int opcode() { return 0x23; } 10 | @Override public boolean commutes() { return true; } 11 | } 12 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/XorX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class XorX86 extends RegX86 { 6 | XorX86( Node add ) { super(add); } 7 | @Override public String op() { return "xor"; } 8 | @Override public String glabel() { return "^"; } 9 | @Override int opcode() { return 0x33; } 10 | @Override public boolean commutes() { return true; } 11 | } 12 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/AndIRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class AndIRISC extends ImmRISC { 6 | public AndIRISC( Node and, int imm) { super(and,imm); } 7 | @Override public String op() { return "andi"; } 8 | @Override public String glabel() { return "&"; } 9 | @Override int opcode() { return riscv.OP_IMM; } 10 | @Override int func3() {return 7;} 11 | } 12 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/OrIRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class OrIRISC extends ImmRISC { 6 | public OrIRISC( Node and, int imm) { super(and,imm); } 7 | @Override int opcode() { return riscv.OP_IMM; } 8 | @Override int func3() { return 6; } 9 | @Override public String glabel() { return "|"; } 10 | @Override public String op() { return "ori"; } 11 | } 12 | -------------------------------------------------------------------------------- /optvm/src/main/java/com/compilerprogramming/ezlang/compiler/ExitSSA.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * Converts from SSA form to non-SSA form. 7 | */ 8 | public class ExitSSA { 9 | public ExitSSA(CompiledFunction function, EnumSet options) { 10 | if (options.contains(Options.SSA_DESTRUCTION_BOISSINOT_NOCOALESCE)) 11 | new ExitSSABoissinotNoCoalesce(function,options); 12 | else 13 | new ExitSSABriggs(function,options); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/SllIRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class SllIRISC extends ImmRISC { 6 | public SllIRISC( Node and, int imm) { super(and,imm); } 7 | @Override int opcode() { return riscv.OP_IMM; } 8 | @Override int func3() { return 1; } 9 | @Override public String glabel() { return "<<"; } 10 | @Override public String op() { return "slli"; } 11 | } 12 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/SrlIRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class SrlIRISC extends ImmRISC { 6 | public SrlIRISC( Node and, int imm, boolean pop) { super(and,imm,pop); } 7 | @Override int opcode() { return riscv.OP_IMM; } 8 | @Override int func3() { return 5; } 9 | @Override public String glabel() { return ">>>"; } 10 | @Override public String op() { return "srli"; } 11 | } 12 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/SraIRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class SraIRISC extends ImmRISC { 6 | public SraIRISC( Node and, int imm) { 7 | super(and,imm | (0x20 << 5)); 8 | } 9 | @Override int opcode() { return riscv.OP_IMM; } 10 | @Override int func3() { return 5;} 11 | @Override public String glabel() { return ">>"; } 12 | @Override public String op() { return "srai"; } 13 | } 14 | -------------------------------------------------------------------------------- /common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.compilerprogramming.ezlang 8 | compilercraft 9 | 1.0 10 | 11 | common 12 | jar 13 | Common 14 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/XorIRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class XorIRISC extends ImmRISC { 6 | public XorIRISC( Node and, int imm) { super(and,imm); } 7 | public XorIRISC( Node and, int imm, boolean pop) { super(and,imm,pop); } 8 | @Override int opcode() { return riscv.OP_IMM; } 9 | @Override int func3() { return 4; } 10 | @Override public String glabel() { return "^"; } 11 | @Override public String op() { return "xori"; } 12 | } 13 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/LinkMem.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.codegen; 2 | 3 | // In-memory linking 4 | public class LinkMem { 5 | final CodeGen _code; 6 | LinkMem( CodeGen code ) { _code = code; } 7 | 8 | public CodeGen link() { 9 | Encoding enc = _code._encoding; 10 | 11 | // Patch external calls internally 12 | enc.patchGlobalRelocations(); 13 | 14 | // Write any large constants into a constant pool; they 15 | // are accessed by RIP-relative addressing. 16 | enc.writeConstantPool(enc._bits,true); 17 | 18 | return _code; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/RIPRelSize.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.codegen; 2 | 3 | // This Node rip-relative encodings has sizes that vary by delta 4 | public interface RIPRelSize { 5 | // delta is the distance from the opcode *start* to the target start. Each 6 | // hardware target adjusts as needed, X86 measures from the opcode *end* 7 | // and small jumps are 2 bytes, so they'll need to subtract 2. 8 | byte encSize(int delta); 9 | 10 | // Patch full encoding in. Used for both short and long forms. delta 11 | // again is from the opcode *start*. 12 | void patch( Encoding enc, int opStart, int opLen, int delta ); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/RetARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | 6 | public class RetARM extends ReturnNode implements MachNode { 7 | RetARM(ReturnNode ret, FunNode fun) { super(ret, fun); fun.setRet(this); } 8 | @Override public void encoding( Encoding enc ) { 9 | int frameAdjust = ((FunARM)fun())._frameAdjust; 10 | if( frameAdjust > 0 ) 11 | enc.add4(arm.imm_inst(arm.OPI_ADD, (frameAdjust*-8)&0xFFF, arm.RSP, arm.RSP)); 12 | enc.add4(arm.ret(arm.OP_RET)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/CtrlNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.CodeGen; 4 | import com.compilerprogramming.ezlang.compiler.type.Type; 5 | import java.util.BitSet; 6 | 7 | public class CtrlNode extends CFGNode { 8 | public CtrlNode() { super(CodeGen.CODE._start); } 9 | @Override public String label() { return "Ctrl"; } 10 | @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { return sb.append("Cctrl"); } 11 | @Override public boolean isConst() { return true; } 12 | @Override public Type compute() { return Type.CONTROL; } 13 | @Override public Node idealize() { return null; } 14 | } 15 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/ProjARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 4 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 5 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 6 | import com.compilerprogramming.ezlang.compiler.node.ProjNode; 7 | 8 | public class ProjARM extends ProjNode implements MachNode { 9 | ProjARM( ProjNode p ) { super(p); } 10 | @Override public RegMask regmap(int i) { return null; } 11 | @Override public RegMask outregmap() { 12 | return ((MachNode)in(0)).outregmap(_idx); 13 | } 14 | @Override public void encoding( Encoding enc ) { } 15 | } 16 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/XCtrlNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.CodeGen; 4 | import com.compilerprogramming.ezlang.compiler.type.Type; 5 | import java.util.BitSet; 6 | 7 | public class XCtrlNode extends CFGNode { 8 | public XCtrlNode() { super(new Node[]{CodeGen.CODE._start}); } 9 | @Override public String label() { return "Xctrl"; } 10 | @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { return sb.append("Xctrl"); } 11 | @Override public boolean isConst() { return true; } 12 | @Override public Type compute() { return Type.XCONTROL; } 13 | @Override public Node idealize() { return null; } 14 | } 15 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/ProjRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 4 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 5 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 6 | import com.compilerprogramming.ezlang.compiler.node.ProjNode; 7 | 8 | public class ProjRISC extends ProjNode implements MachNode { 9 | ProjRISC(ProjNode p) { super(p); } 10 | @Override public RegMask regmap(int i) { return null; } 11 | @Override public RegMask outregmap() { 12 | return ((MachNode)in(0)).outregmap(_idx); 13 | } 14 | @Override public void encoding( Encoding enc ) { } 15 | } 16 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/ProjX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 4 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 5 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 6 | import com.compilerprogramming.ezlang.compiler.node.ProjNode; 7 | 8 | public class ProjX86 extends ProjNode implements MachNode { 9 | ProjX86( ProjNode p ) { super(p); } 10 | @Override public RegMask regmap(int i) { return null; } 11 | @Override public RegMask outregmap() { 12 | return ((MachNode)in(0)).outregmap(_idx); 13 | } 14 | @Override public void encoding( Encoding enc ) {} 15 | } 16 | -------------------------------------------------------------------------------- /types/src/test/java/com/compilerprogramming/ezlang/types/TestTypes.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.types; 2 | 3 | public class TestTypes { 4 | 5 | EZType buildStruct1(TypeDictionary typeDictionary) { 6 | EZType.EZTypeStruct s = new EZType.EZTypeStruct("S1"); 7 | s.addField("a", typeDictionary.INT); 8 | s.addField("b", typeDictionary.INT); 9 | s.complete(); 10 | return typeDictionary.intern(s); 11 | } 12 | 13 | EZType buildStruct2(TypeDictionary typeDictionary) { 14 | EZType.EZTypeStruct s = new EZType.EZTypeStruct("S2"); 15 | s.addField("a", typeDictionary.INT); 16 | s.addField("b", typeDictionary.INT); 17 | s.complete(); 18 | return typeDictionary.intern(s); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/SetIRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | // corresponds to slti,sltiu 6 | public class SetIRISC extends ImmRISC { 7 | final boolean _unsigned; // slti vs sltiu 8 | public SetIRISC( Node src, int imm12, boolean unsigned ) { 9 | super(src,imm12); 10 | _unsigned = unsigned; 11 | } 12 | @Override public String op() { return "slt" + (_unsigned ? "u":"") + "i"; } 13 | @Override public String glabel() { return "<"+ (_unsigned ? "u":""); } 14 | @Override int opcode() { return 0b0010011; } 15 | @Override int func3() { return _unsigned ? 0b011 : 0b010; } 16 | } 17 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/NeverNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeTuple; 5 | 6 | import java.util.BitSet; 7 | 8 | // "Never true" for infinite loop exits 9 | public class NeverNode extends IfNode { 10 | public NeverNode(NeverNode ctrl) { super(ctrl); } 11 | public NeverNode(Node ctrl) { super(ctrl,null); } 12 | 13 | @Override public String label() { return "Never"; } 14 | 15 | @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { return sb.append("Never"); } 16 | 17 | @Override public Type compute() { return TypeTuple.IF_BOTH; } 18 | 19 | @Override public Node idealize() { return null; } 20 | } 21 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/ParmARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 4 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 5 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 6 | import com.compilerprogramming.ezlang.compiler.node.ParmNode; 7 | 8 | public class ParmARM extends ParmNode implements MachNode { 9 | final RegMask _rmask; 10 | ParmARM(ParmNode parm) { 11 | super(parm); 12 | _rmask = arm.callInMask(fun().sig(),_idx,0); 13 | } 14 | @Override public RegMask regmap(int i) { return null; } 15 | @Override public RegMask outregmap() { return _rmask; } 16 | @Override public void encoding( Encoding enc ) { } 17 | } 18 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/ParmRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 4 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 5 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 6 | import com.compilerprogramming.ezlang.compiler.node.ParmNode; 7 | 8 | public class ParmRISC extends ParmNode implements MachNode { 9 | final RegMask _rmask; 10 | ParmRISC(ParmNode parm) { 11 | super(parm); 12 | _rmask = riscv.callInMask(fun().sig(),_idx,0); 13 | } 14 | @Override public RegMask regmap(int i) { return null; } 15 | @Override public RegMask outregmap() { return _rmask; } 16 | @Override public void encoding( Encoding enc ) { } 17 | } 18 | -------------------------------------------------------------------------------- /seaofnodes/src/test/java/com/compilerprogramming/ezlang/compiler/Main.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.CodeGen; 4 | 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | 8 | public class Main { 9 | public static final String PORTS = "com.compilerprogramming.ezlang.compiler.node.cpus"; 10 | // Compile and run a simple program 11 | public static void main( String[] args ) throws Exception { 12 | // First arg is file, 2nd+ args are program args 13 | String src = Files.readString(Path.of(args[0])); 14 | CodeGen code = new CodeGen(src); 15 | code.parse().opto().typeCheck().GCM().localSched(); 16 | System.out.println(code._stop); 17 | //System.out.println(Eval2.eval(code,arg,100000)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/ExternNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.type.Type; 5 | 6 | import java.util.BitSet; 7 | 8 | /** 9 | A constant with external linkage. 10 | */ 11 | 12 | public class ExternNode extends ConstantNode { 13 | public final String _extern; 14 | public ExternNode(Type t, String ex) { super(t); _extern = ex; } 15 | 16 | @Override public String label() { return "#"+_con+":"+_extern; } 17 | @Override public String glabel() { return _con.print(new SB().p("#")).p(":").p(_extern).toString(); } 18 | @Override public String uniqueName() { return "Extern_" + _nid; } 19 | 20 | @Override public boolean eq(Node n) { return this==n; } 21 | } 22 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/ParmX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 4 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 5 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 6 | import com.compilerprogramming.ezlang.compiler.node.ParmNode; 7 | 8 | public class ParmX86 extends ParmNode implements MachNode { 9 | final RegMask _rmask; 10 | ParmX86( ParmNode parm ) { 11 | super(parm); 12 | _rmask = x86_64_v2.callInMask(fun().sig(),_idx,1/*RPC*/); 13 | } 14 | @Override public RegMask regmap(int i) { return null; } 15 | @Override public RegMask outregmap() { return _rmask; } 16 | @Override public void encoding( Encoding enc ) { } 17 | } 18 | -------------------------------------------------------------------------------- /lexer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.compilerprogramming.ezlang 8 | compilercraft 9 | 1.0 10 | 11 | lexer 12 | jar 13 | Lexer 14 | 15 | 16 | com.compilerprogramming.ezlang 17 | common 18 | 1.0 19 | 20 | 21 | -------------------------------------------------------------------------------- /types/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.compilerprogramming.ezlang 8 | compilercraft 9 | 1.0 10 | 11 | types 12 | jar 13 | Types 14 | 15 | 16 | com.compilerprogramming.ezlang 17 | common 18 | 1.0 19 | 20 | 21 | -------------------------------------------------------------------------------- /semantic/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.compilerprogramming.ezlang 8 | compilercraft 9 | 1.0 10 | 11 | semantic 12 | jar 13 | Semantic 14 | 15 | 16 | com.compilerprogramming.ezlang 17 | parser 18 | 1.0 19 | 20 | 21 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/OrRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class OrRISC extends MachConcreteNode implements MachNode { 8 | public OrRISC(Node or) { super(or); } 9 | @Override public String op() { return "or"; } 10 | @Override public RegMask regmap(int i) { return riscv.RMASK; } 11 | @Override public RegMask outregmap() { return riscv.WMASK; } 12 | @Override public void encoding( Encoding enc ) { riscv.r_type(enc,this,6,0); } 13 | @Override public void asm(CodeGen code, SB sb) { 14 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" | ").p(code.reg(in(2))); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/XorRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class XorRISC extends MachConcreteNode implements MachNode { 8 | public XorRISC(Node or) { super(or); } 9 | @Override public String op() { return "xor"; } 10 | @Override public RegMask regmap(int i) { return riscv.RMASK; } 11 | @Override public RegMask outregmap() { return riscv.WMASK; } 12 | @Override public void encoding( Encoding enc ) { riscv.r_type(enc,this,4,0); } 13 | @Override public void asm(CodeGen code, SB sb) { 14 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" ^ ").p(code.reg(in(2))); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/AndRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class AndRISC extends MachConcreteNode implements MachNode { 8 | public AndRISC(Node and) { super(and); } 9 | @Override public String op() { return "and"; } 10 | @Override public RegMask regmap(int i) { return riscv.RMASK; } 11 | @Override public RegMask outregmap() { return riscv.WMASK; } 12 | @Override public void encoding( Encoding enc ) { riscv.r_type(enc,this,0b111,0); } 13 | @Override public void asm(CodeGen code, SB sb) { 14 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" & ").p(code.reg(in(2))); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/DivRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class DivRISC extends MachConcreteNode implements MachNode{ 8 | public DivRISC(Node div) {super(div);} 9 | @Override public String op() { return "div"; } 10 | @Override public RegMask regmap(int i) { return riscv.RMASK; } 11 | @Override public RegMask outregmap() { return riscv.WMASK; } 12 | @Override public void encoding( Encoding enc ) { riscv.r_type(enc,this,4,1); } 13 | @Override public void asm(CodeGen code, SB sb) { 14 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" / ").p(code.reg(in(2))); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/RetX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | 6 | public class RetX86 extends ReturnNode implements MachNode { 7 | RetX86( ReturnNode ret, FunNode fun ) { super(ret, fun); fun.setRet(this); } 8 | @Override public void encoding( Encoding enc ) { 9 | int sz = fun()._frameAdjust; 10 | if( sz != 0 ) { 11 | enc.add1( x86_64_v2.REX_W ).add1( x86_64_v2.imm8(sz) ? 0x83 : 0x81 ); 12 | enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0b000, x86_64_v2.RSP) ); 13 | if( x86_64_v2.imm8(sz) ) enc.add1(sz); 14 | else enc.add4(sz); 15 | } 16 | enc.add1(0xC3); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/SubRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class SubRISC extends MachConcreteNode implements MachNode { 8 | public SubRISC( Node sub ) { super(sub); } 9 | @Override public String op() { return "sub"; } 10 | @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.RMASK; } 11 | @Override public RegMask outregmap() { return riscv.WMASK; } 12 | @Override public void encoding( Encoding enc ) { riscv.r_type(enc,this,0,0x20); } 13 | @Override public void asm(CodeGen code, SB sb) { 14 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" - ").p(code.reg(in(2))); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/SllRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | // Shift left logical 8 | public class SllRISC extends MachConcreteNode implements MachNode { 9 | public SllRISC(Node sll) { super(sll); } 10 | @Override public String op() { return "shl"; } 11 | @Override public RegMask regmap(int i) { return riscv.RMASK; } 12 | @Override public RegMask outregmap() { return riscv.WMASK; } 13 | @Override public void encoding( Encoding enc ) { riscv.r_type(enc,this,1,0); } 14 | @Override public void asm(CodeGen code, SB sb) { 15 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" << ").p(code.reg(in(2))); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/AsrARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | // Arithmetic Shift Right (register) 8 | public class AsrARM extends MachConcreteNode implements MachNode { 9 | AsrARM(Node asr) {super(asr);} 10 | @Override public String op() { return "sar"; } 11 | @Override public RegMask regmap(int i) { return arm.RMASK; } 12 | @Override public RegMask outregmap() { return arm.DMASK; } 13 | @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,arm.OP_ASR); } 14 | @Override public void asm(CodeGen code, SB sb) { 15 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" >> ").p(code.reg(in(2))); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/SrlRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | // Right Shift Logical 8 | public class SrlRISC extends MachConcreteNode implements MachNode { 9 | public SrlRISC(Node srli) { super(srli); } 10 | @Override public String op() { return "shr"; } 11 | @Override public RegMask regmap(int i) { return riscv.RMASK; } 12 | @Override public RegMask outregmap() { return riscv.WMASK; } 13 | @Override public void encoding( Encoding enc ) { riscv.r_type(enc,this,7,0); } 14 | @Override public void asm(CodeGen code, SB sb) { 15 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" >>> ").p(code.reg(in(2))); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/LslARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | // Logical Shift Left (register) 8 | public class LslARM extends MachConcreteNode implements MachNode { 9 | LslARM(Node asr) {super(asr);} 10 | @Override public String op() { return "shr"; } 11 | @Override public RegMask regmap(int i) { return arm.RMASK; } 12 | @Override public RegMask outregmap() { return arm.WMASK; } 13 | 14 | @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,arm.OP_LSL); } 15 | @Override public void asm(CodeGen code, SB sb) { 16 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" << ").p(code.reg(in(2))); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/LsrARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | // Logical Shift Right (register) 8 | public class LsrARM extends MachConcreteNode implements MachNode { 9 | LsrARM(Node asr) {super(asr);} 10 | @Override public String op() { return "shr"; } 11 | @Override public RegMask regmap(int i) { return arm.RMASK; } 12 | @Override public RegMask outregmap() { return arm.WMASK; } 13 | 14 | @Override public void encoding( Encoding enc ) { arm.shift_reg(enc,this,arm.OP_LSR); } 15 | @Override public void asm(CodeGen code, SB sb) { 16 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" >>> ").p(code.reg(in(2))); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/AddFRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | // fadd.d 8 | public class AddFRISC extends MachConcreteNode implements MachNode { 9 | AddFRISC(Node addf) {super(addf);} 10 | @Override public String op() { return "addf"; } 11 | @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } 12 | @Override public RegMask outregmap() { return riscv.FMASK; } 13 | @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,1); } 14 | @Override public void asm(CodeGen code, SB sb) { 15 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2))); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/MulFRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | // fmul.d 8 | public class MulFRISC extends MachConcreteNode implements MachNode { 9 | MulFRISC(Node mulf) {super(mulf);} 10 | @Override public String op() { return "mulf"; } 11 | @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } 12 | @Override public RegMask outregmap() { return riscv.FMASK; } 13 | @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,9); } 14 | @Override public void asm(CodeGen code, SB sb) { 15 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" * ").p(code.reg(in(2))); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/SraRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | // Right Shift Arithmetic 8 | public class SraRISC extends MachConcreteNode implements MachNode { 9 | public SraRISC(Node sra) { super(sra); } 10 | @Override public String op() { return "sar"; } 11 | @Override public RegMask regmap(int i) { return riscv.RMASK; } 12 | @Override public RegMask outregmap() { return riscv.WMASK; } 13 | @Override public void encoding( Encoding enc ) { riscv.r_type(enc,this,0b101,0b00100000); } 14 | @Override public void asm(CodeGen code, SB sb) { 15 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" >> ").p(code.reg(in(2))); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/SubFRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | // fsub.d 8 | public class SubFRISC extends MachConcreteNode implements MachNode { 9 | SubFRISC(Node subf) {super(subf);} 10 | @Override public String op() { return "subf"; } 11 | @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } 12 | @Override public RegMask outregmap() { return riscv.FMASK; } 13 | @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,5); } 14 | @Override public void asm(CodeGen code, SB sb) { 15 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2))); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/SubARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class SubARM extends MachConcreteNode implements MachNode { 8 | SubARM(Node sub) { super(sub); } 9 | @Override public String op() { return "sub"; } 10 | @Override public RegMask regmap(int i) { return arm.RMASK; } 11 | @Override public RegMask outregmap() { return arm.WMASK; } 12 | 13 | @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,arm.OP_SUB); } 14 | 15 | // General form: "sub # rd = rs1 - rs2" 16 | @Override public void asm(CodeGen code, SB sb) { 17 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" - ").p(code.reg(in(2))); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/DivARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class DivARM extends MachConcreteNode implements MachNode { 8 | DivARM( Node div ) { super(div); } 9 | @Override public String op() { return "div"; } 10 | @Override public RegMask regmap(int i) { return arm.RMASK; } 11 | @Override public RegMask outregmap() { return arm.WMASK; } 12 | // SDIV 13 | @Override public void encoding( Encoding enc ) { arm.madd(enc,this,arm.OP_DIV,3); } 14 | // General form: "div dst /= src" 15 | @Override public void asm(CodeGen code, SB sb) { 16 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" / ").p(code.reg(in(2))); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/AddARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class AddARM extends MachConcreteNode implements MachNode { 8 | AddARM( Node add) { super(add); } 9 | @Override public String op() { return "add"; } 10 | @Override public RegMask regmap(int i) { return arm.RMASK; } 11 | @Override public RegMask outregmap() { return arm.WMASK; } 12 | 13 | // ADD (shifted register) 14 | @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,arm.OP_ADD); } 15 | // General form: "rd = rs1 + rs2" 16 | @Override public void asm(CodeGen code, SB sb) { 17 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2))); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/DivFARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class DivFARM extends MachConcreteNode implements MachNode { 8 | DivFARM( Node divf) { super(divf); } 9 | @Override public String op() { return "divf"; } 10 | @Override public RegMask regmap(int i) { return arm.DMASK; } 11 | @Override public RegMask outregmap() { return arm.DMASK; } 12 | 13 | // FDIV (scalar) 14 | @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,arm.OPF_DIV); } 15 | // General form: "VDIF = dst /= src" 16 | @Override public void asm(CodeGen code, SB sb) { 17 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" / ").p(code.reg(in(2))); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/MulRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | // mulh signed multiply instruction(no-imm form) 8 | public class MulRISC extends MachConcreteNode implements MachNode{ 9 | public MulRISC(Node mul) {super(mul);} 10 | @Override public String op() { return "mul"; } 11 | @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.RMASK; } 12 | @Override public RegMask outregmap() { return riscv.WMASK; } 13 | @Override public void encoding( Encoding enc ) { riscv.r_type(enc,this,0,1); } 14 | @Override public void asm(CodeGen code, SB sb) { 15 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" * ").p(code.reg(in(2))); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/CastMach.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.CodeGen; 5 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 6 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 7 | 8 | /** 9 | * Cast a pointer to read-only 10 | */ 11 | public class CastMach extends CastNode implements MachNode { 12 | public CastMach( CastNode n ) { super(n); } 13 | @Override public String op() { return label(); } 14 | @Override public RegMask regmap(int i) { assert i==1; return RegMask.FULL; } 15 | @Override public RegMask outregmap() { return RegMask.FULL; } 16 | @Override public int twoAddress( ) { return 1; } 17 | @Override public void encoding( Encoding enc ) { } 18 | @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(in(1))); } 19 | } 20 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Java CI with Maven 10 | 11 | on: 12 | push: 13 | branches: [ "main" ] 14 | pull_request: 15 | branches: [ "main" ] 16 | 17 | jobs: 18 | build: 19 | 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Set up JDK 21 25 | uses: actions/setup-java@v4 26 | with: 27 | java-version: '21' 28 | distribution: 'temurin' 29 | cache: maven 30 | - name: Build with Maven 31 | run: mvn test 32 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/MulARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | // mulh signed multiply instruction(no-imm form) 8 | public class MulARM extends MachConcreteNode implements MachNode { 9 | MulARM(Node mul) {super(mul);} 10 | @Override public String op() { return "mul"; } 11 | @Override public RegMask regmap(int i) { return arm.RMASK; } 12 | @Override public RegMask outregmap() { return arm.WMASK; } 13 | 14 | @Override public void encoding( Encoding enc ) { arm.madd(enc,this,arm.OP_MUL,31); } 15 | // General form: "rd = rs1 * rs2" 16 | @Override public void asm(CodeGen code, SB sb) { 17 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" * ").p(code.reg(in(2))); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/XorARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class XorARM extends MachConcreteNode implements MachNode{ 8 | XorARM(Node xor) {super(xor);} 9 | @Override public String op() { return "xor"; } 10 | @Override public String glabel() { return "^"; } 11 | @Override public RegMask regmap(int i) { return arm.RMASK; } 12 | @Override public RegMask outregmap() { return arm.WMASK; } 13 | @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,arm.OP_XOR); } 14 | // General form: "rd = x1 ^ x2" 15 | @Override public void asm(CodeGen code, SB sb) { 16 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" ^ ").p(code.reg(in(2))); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/DivNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.TypeInteger; 4 | 5 | public class DivNode extends ArithNode { 6 | public DivNode(Node lhs, Node rhs) { super(lhs, rhs); } 7 | 8 | @Override public String label() { return "Div"; } 9 | @Override public String op() { return "//"; } 10 | 11 | @Override long doOp( long x, long y ) { return y==0 ? 0 : x / y; } 12 | @Override TypeInteger doOp(TypeInteger x, TypeInteger y) { 13 | return TypeInteger.BOT; 14 | } 15 | 16 | @Override 17 | public Node idealize() { 18 | // Div of 1. 19 | if( in(2)._type == TypeInteger.TRUE ) 20 | return in(1); 21 | return super.idealize(); 22 | } 23 | 24 | @Override Node copy(Node lhs, Node rhs) { return new DivNode(lhs,rhs); } 25 | @Override Node copyF() { return new DivFNode(null,null); } 26 | } 27 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/MultiNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.Ary; 4 | 5 | 6 | public interface MultiNode { 7 | 8 | abstract Ary outs(); 9 | 10 | // Find a projection by index 11 | default ProjNode proj( int idx ) { 12 | for( Node out : outs() ) 13 | if( out instanceof ProjNode prj && prj._idx==idx ) 14 | return prj; 15 | return null; 16 | } 17 | 18 | // Find a projection by index 19 | default CProjNode cproj( int idx ) { 20 | for( Node out : outs() ) 21 | if( out instanceof CProjNode prj && prj._idx==idx ) 22 | return prj; 23 | return null; 24 | } 25 | 26 | // Return not-null if this projection index is a ideal copy. 27 | // Called by ProjNode ideal and used to collapse Multis. 28 | default Node pcopy(int idx) { return null; } 29 | } 30 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/ReadOnlyMach.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.CodeGen; 5 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 6 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 7 | 8 | /** 9 | * Cast a pointer to read-only 10 | */ 11 | public class ReadOnlyMach extends ReadOnlyNode implements MachNode { 12 | public ReadOnlyMach( ReadOnlyNode n ) { super(n); } 13 | @Override public String op() { return label(); } 14 | @Override public RegMask regmap(int i) { assert i==1; return RegMask.FULL; } 15 | @Override public RegMask outregmap() { return RegMask.FULL; } 16 | @Override public int twoAddress( ) { return 1; } 17 | @Override public void encoding( Encoding enc ) { } 18 | @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(in(1))); } 19 | } 20 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/MulFARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class MulFARM extends MachConcreteNode implements MachNode{ 8 | MulFARM(Node mulf) {super(mulf);} 9 | @Override public String op() { return "mulf"; } 10 | @Override public RegMask regmap(int i) { return arm.DMASK; } 11 | @Override public RegMask outregmap() { return arm.DMASK; } 12 | @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,arm.OPF_MUL); } 13 | // Default on double precision for now(64 bits) 14 | // General form: "VMUL.f32 rd = src1 * src2 15 | @Override public void asm(CodeGen code, SB sb) { 16 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" * ").p(code.reg(in(2))); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/SubFARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class SubFARM extends MachConcreteNode implements MachNode { 8 | SubFARM(Node subf) {super(subf);} 9 | @Override public String op() { return "subf"; } 10 | @Override public RegMask regmap(int i) { return arm.DMASK; } 11 | @Override public RegMask outregmap() { return arm.DMASK; } 12 | @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,arm.OPF_SUB); } 13 | // Default on double precision for now(64 bits) 14 | // General form: "vsub.f32 rd = src1 + src2 15 | @Override public void asm(CodeGen code, SB sb) { 16 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" - ").p(code.reg(in(2))); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/NegRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class NegRISC extends MachConcreteNode implements MachNode { 8 | public NegRISC( Node neg ) { super(neg); } 9 | @Override public String op() { return "neg"; } 10 | @Override public RegMask regmap(int i) { assert i==1; return riscv.RMASK; } 11 | @Override public RegMask outregmap() { return riscv.WMASK; } 12 | @Override public void encoding( Encoding enc ) { 13 | short dst = enc.reg(this ); 14 | short src = enc.reg(in(1)); 15 | riscv.r_type(riscv.OP,dst,0,0,src,0x20); 16 | } 17 | @Override public void asm(CodeGen code, SB sb) { 18 | sb.p(code.reg(this)).p(" = -").p(code.reg(in(1))); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/NewX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class NewX86 extends NewNode implements MachNode { 8 | // A pre-zeroed chunk of memory. 9 | NewX86( NewNode nnn ) { super(nnn); } 10 | @Override public void encoding( Encoding enc ) { 11 | enc.external(this,"calloc"); 12 | // ldi rcx,#1 // number of elements to calloc 13 | enc.add1(0xB8 + _arg2Reg).add4(1); 14 | // E8 cd CALL rel32; 15 | enc.add1(0xE8); 16 | enc.add4(0); // offset 17 | } 18 | // General form: "alloc #bytes PC" 19 | @Override public void asm(CodeGen code, SB sb) { 20 | sb.p("ldi rcx = #1\n"); 21 | sb.p("call #calloc"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /seaofnodes/src/test/cases/sieve/sieve.smp: -------------------------------------------------------------------------------- 1 | // -*- mode: java; -*- 2 | val sieve = { int N -> 3 | // The main Sieve array 4 | bool[] !ary = new bool[N]; 5 | // The primes less than N 6 | u32[] !primes = new u32[N>>1]; 7 | // Number of primes so far, searching at index p 8 | int nprimes = 0, p=2; 9 | // Find primes while p^2 < N 10 | while( p*p < N ) { 11 | // skip marked non-primes 12 | while( ary[p] ) p++; 13 | // p is now a prime 14 | primes[nprimes++] = p; 15 | // Mark out the rest non-primes 16 | for( int i = p + p; i < ary#; i+= p ) 17 | ary[i] = true; 18 | p++; 19 | } 20 | 21 | // Now just collect the remaining primes, no more marking 22 | for( ; p < N; p++ ) 23 | if( !ary[p] ) 24 | primes[nprimes++] = p; 25 | 26 | // Copy/shrink the result array 27 | u32[] !rez = new u32[nprimes]; 28 | for( int j=0; j < nprimes; j++ ) 29 | rez[j] = primes[j]; 30 | return rez; 31 | }; -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/OrARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | // Not using the ORRS variant. 8 | public class OrARM extends MachConcreteNode implements MachNode { 9 | OrARM(Node and) { super(and); } 10 | @Override public String op() { return "or"; } 11 | @Override public String glabel() { return "|"; } 12 | @Override public RegMask regmap(int i) { return arm.RMASK; } 13 | @Override public RegMask outregmap() { return arm.WMASK; } 14 | @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,arm.OP_OR); } 15 | // General form: #rd = rs1 & rs2 16 | @Override public void asm(CodeGen code, SB sb) { 17 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" | ").p(code.reg(in(2))); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /common/src/main/java/com/compilerprogramming/ezlang/exceptions/CompilerException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DO NOT REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 | *

4 | * Contributor(s): 5 | *

6 | * The Initial Developer of the Original Software is Dibyendu Majumdar. 7 | *

8 | * This file is part of the Sea Of Nodes Simple Programming language 9 | * implementation. See https://github.com/SeaOfNodes/Simple 10 | *

11 | * The contents of this file are subject to the terms of the 12 | * Apache License Version 2 (the "APL"). You may not use this 13 | * file except in compliance with the License. A copy of the 14 | * APL may be obtained from: 15 | * http://www.apache.org/licenses/LICENSE-2.0 16 | */ 17 | package com.compilerprogramming.ezlang.exceptions; 18 | 19 | public class CompilerException extends RuntimeException { 20 | public CompilerException(String message) { 21 | super(message); 22 | } 23 | 24 | public CompilerException(String message, Throwable cause) { 25 | super(message, cause); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/RetRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 4 | import com.compilerprogramming.ezlang.compiler.node.FunNode; 5 | import com.compilerprogramming.ezlang.compiler.node.ReturnNode; 6 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 7 | import com.compilerprogramming.ezlang.compiler.util.Utils; 8 | 9 | public class RetRISC extends ReturnNode implements MachNode { 10 | public RetRISC(ReturnNode ret, FunNode fun) { super(ret, fun); fun.setRet(this); } 11 | @Override public void encoding( Encoding enc ) { 12 | int sz = fun()._frameAdjust; 13 | if( sz >= 1L<<12 ) throw Utils.TODO(); 14 | if( sz != 0 ) 15 | enc.add4(riscv.i_type(riscv.OP_IMM, riscv.RSP, 0, riscv.RSP, sz & 0xFFF)); 16 | short rpc = enc.reg(rpc()); 17 | enc.add4(riscv.i_type(riscv.OP_JALR, riscv.ZERO, 0, rpc, 0)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/AddIRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | public class AddIRISC extends ImmRISC { 6 | // Used to inst-selection as a direct match against an ideal Add/Sub 7 | public AddIRISC( Node add, int imm12, boolean pop ) { super(add,imm12,pop); } 8 | @Override public String op() { return "addi"; } 9 | @Override public String glabel() { return "+"; } 10 | @Override int opcode() { return riscv.OP_IMM; } 11 | @Override int func3() {return 0;} 12 | @Override public AddIRISC copy() { 13 | // Clone the AddI, using the same inputs-only code used during inst select. 14 | // Output edges are missing. 15 | AddIRISC add = new AddIRISC(in(1),_imm12,false); 16 | // Copys happen when output edges should be valid, so correct missing output edges. 17 | in(1)._outputs.add(add); 18 | return add; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /seaofnodes/src/test/cases/fib/fib.ez_out: -------------------------------------------------------------------------------- 1 | ---foo { -> int #0}--------------------------- 2 | 0030 4883EC08 subi rsp -= #8 3 | 0034 BF0A000000 ldi rdi = #10 4 | 0039 E8C2FFFFFF call fib rdi 5 | 003E 4883C408C3 addi rsp += #8 6 | 0043 ret 7 | ---{ -> int #0}--------------------------- 8 | 9 | ---fib { int -> int #1}--------------------------- 10 | n:rdi 11 | 0000 BA01000000 ldi rdx = #1 12 | 0005 B901000000 ldi rcx = #1 13 | LOOP5: 14 | i:rdi,f2:rdx,f1:rcx 15 | 000A 488BC2 mov rax = rdx // def/self #0 16 | 000D 4883FF01 cmp rdi, #1 17 | 0011 7E0E j<= L3 // L8 18 | L8: 19 | 0013 48FFCF dec rdi += #-1 20 | 0016 488BD0 mov rdx = rax // use/self/use #0 21 | 0019 4803D1 add rdx += rcx 22 | 001C 488BC8 mov rcx = rax // use/self/use #0 23 | 001F EBE9 jmp LOOP5 24 | L51: 25 | L3: 26 | 0021 C3 ret 27 | ---{ int -> int #1}--------------------------- -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/AddFARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class AddFARM extends MachConcreteNode implements MachNode { 8 | AddFARM(Node addf) { super(addf); } 9 | @Override public String op() { return "addf"; } 10 | @Override public RegMask regmap(int i) { return arm.DMASK; } 11 | @Override public RegMask outregmap() { return arm.DMASK; } 12 | 13 | //FADD (scalar) 14 | @Override public void encoding( Encoding enc ) { arm.f_scalar(enc,this,arm.OPF_OP_ADD);} 15 | 16 | // Default on double precision for now(64 bits) 17 | // General form: "addf rd = src1 + src2 18 | @Override public void asm(CodeGen code, SB sb) { 19 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2))); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/CmpARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class CmpARM extends MachConcreteNode implements MachNode { 8 | CmpARM( Node cmp ) { super(cmp); } 9 | @Override public String op() { return "cmp"; } 10 | @Override public RegMask regmap(int i) { return arm.RMASK; } 11 | @Override public RegMask outregmap() { return arm.FLAGS_MASK; } 12 | 13 | // SUBS (shifted register) 14 | @Override public void encoding( Encoding enc ) { arm.r_reg_subs(enc,this,arm.OP_CMP); } 15 | 16 | // General form: "cmp rs1, rs2" 17 | @Override public void asm(CodeGen code, SB sb) { 18 | String dst = code.reg(this); 19 | if( dst!="flags" ) sb.p(dst).p(" = "); 20 | sb.p(code.reg(in(1))).p(", ").p(code.reg(in(2))); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/AddRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class AddRISC extends MachConcreteNode implements MachNode { 8 | public AddRISC( Node add ) { super(add); } 9 | AddRISC( Node base, Node off ) { 10 | super(new Node[3]); 11 | _inputs.set(1,base); 12 | _inputs.set(2,off ); 13 | } 14 | @Override public String op() { return "add"; } 15 | @Override public RegMask regmap(int i) { return riscv.RMASK; } 16 | @Override public RegMask outregmap() { return riscv.WMASK; } 17 | @Override public void encoding( Encoding enc ) { riscv.r_type(enc,this,0,0); } 18 | @Override public void asm(CodeGen code, SB sb) { 19 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2))); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/DivFRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | // fdiv.d 8 | public class DivFRISC extends MachConcreteNode implements MachNode{ 9 | DivFRISC(Node divf) {super(divf);} 10 | @Override public String op() { return "divf"; } 11 | @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } 12 | @Override public RegMask outregmap() { return riscv.FMASK; } 13 | @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RUP,13); } 14 | // Default on double precision for now(64 bits) 15 | // General form: "fdiv.d rd = src1 / src2 16 | @Override public void asm(CodeGen code, SB sb) { 17 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" / ").p(code.reg(in(2))); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/AddIX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 4 | import com.compilerprogramming.ezlang.compiler.node.Node; 5 | 6 | public class AddIX86 extends ImmX86 { 7 | AddIX86( Node add, int imm ) { super(add,imm); } 8 | @Override public String op() { 9 | return _imm == 1 ? "inc" : (_imm == -1 ? "dec" : "addi"); 10 | } 11 | @Override public String glabel() { return "+"; } 12 | @Override int opcode() { return 0x81; } 13 | @Override int mod() { return 0; } 14 | @Override public final void encoding( Encoding enc ) { 15 | if( _imm== 1 || _imm== -1 ) { 16 | short dst = enc.reg(this); // Also src1 17 | enc.add1( x86_64_v2.rex(0,dst,0)); 18 | enc.add1(0xFF); 19 | enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, _imm==1 ? 0 : 1, dst) ); 20 | } else super.encoding(enc); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /seaofnodes/src/test/cases/fib/fib.smp_out: -------------------------------------------------------------------------------- 1 | ---main { int -> int #0}--------------------------- 2 | 0000 4883EC08 subi rsp -= #8 3 | 0004 BF0A000000 ldi rdi = #10 4 | 0009 E812000000 call fib rdi 5 | 000E 4883C408C3 addi rsp += #8 6 | 0013 ret 7 | ---{ int -> int #0}--------------------------- 8 | 9 | ---fib { int -> int #1}--------------------------- 10 | n:rdi 11 | 0020 BA01000000 ldi rdx = #1 12 | 0025 B901000000 ldi rcx = #1 13 | LOOP14: 14 | i:rdi,f2:rdx,f1:rcx 15 | 002A 488BC2 mov rax = rdx // def/self #0 16 | 002D 4883FF01 cmp rdi, #1 17 | 0031 7E0F j<= L12 // L16 18 | L16: 19 | 0033 4883C7FF dec rdi += #-1 20 | 0037 488BD0 mov rdx = rax // use/self/use #0 21 | 003A 4803D1 add rdx += rcx 22 | 003D 488BC8 mov rcx = rax // use/self/use #0 23 | 0040 EBE8 jmp LOOP14 24 | L52: 25 | L12: 26 | 0042 C3 ret 27 | ---{ int -> int #1}--------------------------- -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/CalleeSaveNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 4 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 5 | import com.compilerprogramming.ezlang.compiler.type.Type; 6 | 7 | public class CalleeSaveNode extends ProjNode implements MachNode { 8 | final RegMask _mask; 9 | public CalleeSaveNode(FunNode fun, int reg, String label) { 10 | super(fun,reg,label); 11 | fun._outputs.pop(); 12 | int i=0; 13 | while( fun.out(i) instanceof PhiNode ) i++; 14 | fun._outputs.insert(this,i); 15 | _mask = new RegMask(reg); 16 | } 17 | @Override public RegMask regmap(int i) { return null; } 18 | @Override public RegMask outregmap() { return _mask; } 19 | @Override public void encoding( Encoding enc ) { } 20 | 21 | @Override public Type compute() { return Type.BOTTOM; } 22 | @Override public Node idealize() { return null; } 23 | } 24 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/CmpFARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | // compare instruction on float regs input(D-registers) 8 | public class CmpFARM extends MachConcreteNode implements MachNode{ 9 | CmpFARM(Node cmp) {super(cmp);} 10 | @Override public String op() { return "cmpf"; } 11 | @Override public RegMask regmap(int i) { return arm.DMASK; } 12 | @Override public RegMask outregmap() { return arm.FLAGS_MASK; } 13 | 14 | // FCMP 15 | @Override public void encoding( Encoding enc ) { arm.f_cmp(enc,this); } 16 | // General form: "cmp d0, d1" 17 | @Override public void asm(CodeGen code, SB sb) { 18 | String dst = code.reg(this); 19 | if( dst!="flags" ) sb.p(dst).p(" = "); 20 | sb.p(code.reg(in(1))).p(", ").p(code.reg(in(2))); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/SetRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | // corresponds to slt sltu 8 | public class SetRISC extends MachConcreteNode implements MachNode { 9 | final boolean _unsigned; 10 | public SetRISC( Node cmp, boolean unsigned ) { super(cmp); _unsigned=unsigned; } 11 | @Override public String op() { return "slt" + (_unsigned ? "u":""); } 12 | @Override public RegMask regmap(int i) { return riscv.RMASK; } 13 | @Override public RegMask outregmap() { return riscv.WMASK; } 14 | @Override public void encoding( Encoding enc ) { 15 | riscv.r_type(enc,this,_unsigned ? 0b011 : 0b010,0); 16 | } 17 | @Override public void asm(CodeGen code, SB sb) { 18 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" < ").p(code.reg(in(2))); 19 | } 20 | } -------------------------------------------------------------------------------- /parser/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.compilerprogramming.ezlang 8 | compilercraft 9 | 1.0 10 | 11 | parser 12 | jar 13 | Parser 14 | 15 | 16 | com.compilerprogramming.ezlang 17 | lexer 18 | 1.0 19 | 20 | 21 | com.compilerprogramming.ezlang 22 | types 23 | 1.0 24 | 25 | 26 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/FunARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.Utils; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.FunNode; 6 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 7 | 8 | public class FunARM extends FunNode implements MachNode { 9 | FunARM(FunNode fun) { super(fun); } 10 | @Override public void computeFrameAdjust(CodeGen code, int maxReg) { 11 | super.computeFrameAdjust(code,maxReg); 12 | if( _hasCalls ) // If non-leaf, pad to 16b 13 | _frameAdjust = ((_frameAdjust+8) & -16); 14 | } 15 | @Override public void encoding( Encoding enc ) { 16 | int sz = _frameAdjust; 17 | if( sz == 0 ) return; // Skip if no frame adjust 18 | if( sz >= 1L<<12 ) throw Utils.TODO(); 19 | enc.add4(arm.imm_inst(arm.OPI_ADD, -sz&0xFFF, arm.RSP, arm.RSP)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/OrIARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class OrIARM extends MachConcreteNode implements MachNode { 8 | final int _imm; 9 | OrIARM(Node or, int imm) { 10 | super(or); 11 | _inputs.pop(); 12 | _imm = imm; 13 | } 14 | @Override public String op() { return "ori"; } 15 | @Override public RegMask regmap(int i) { return arm.RMASK; } 16 | @Override public RegMask outregmap() { return arm.WMASK; } 17 | @Override public void encoding( Encoding enc ) { 18 | arm.imm_inst_n(enc, this, in(1), arm.OPI_OR, _imm); 19 | } 20 | // General form: "ori rd = rs1 | imm" 21 | @Override public void asm(CodeGen code, SB sb) { 22 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" | #").p(_imm); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/FunRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.Utils; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.FunNode; 6 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 7 | 8 | public class FunRISC extends FunNode implements MachNode { 9 | FunRISC(FunNode fun) {super(fun);} 10 | @Override public void computeFrameAdjust(CodeGen code, int maxReg) { 11 | super.computeFrameAdjust(code,maxReg); 12 | if( _hasCalls ) // If non-leaf, pad to 16b 13 | _frameAdjust = ((_frameAdjust+8) & -16); 14 | } 15 | @Override public void encoding( Encoding enc ) { 16 | int sz = _frameAdjust; 17 | if( sz == 0 ) return; // Skip if no frame adjust 18 | if( sz >= 1L<<12 ) throw Utils.TODO(); 19 | enc.add4(riscv.i_type(riscv.OP_IMM, riscv.RSP, 0, riscv.RSP, -sz & 0xFFF)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /antlr-parser/examples/all-features.lang: -------------------------------------------------------------------------------- 1 | struct Tree { 2 | var left: Tree? 3 | var right: Tree? 4 | } 5 | struct Test { 6 | var intArray: [Int] 7 | } 8 | struct TreeArray { 9 | var array: [Tree?]? 10 | } 11 | func print(n: Int) {} 12 | func foo(a: Int, b: [Int]) { 13 | while(1) { 14 | if (a > b.length) 15 | break 16 | print(b[a]) 17 | a = a + 1 18 | a = a + 2 19 | } 20 | } 21 | func bar() -> Test { 22 | var v = new Test { intArray = new [Tree] { new Tree{left=null,right=null} } } 23 | return v 24 | } 25 | func main() { 26 | var m = 42 27 | var j: Int 28 | var t: Tree 29 | var array = new [Int] {size=10,1,2,3} 30 | array[1] = 42 31 | t.left = null 32 | if (m < 1) 33 | print(1) 34 | else if (m == 5) 35 | print(2) 36 | else 37 | print(3) 38 | } 39 | func fib(n: Int)->Int { 40 | var f1=1 41 | var f2=1 42 | var i=n 43 | while( i>1 ){ 44 | var temp = f1+f2 45 | f1=f2 46 | f2=temp 47 | i=i-1 48 | } 49 | return f2 50 | } 51 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/AndIARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class AndIARM extends MachConcreteNode implements MachNode { 8 | final int _imm; 9 | AndIARM(Node and, int imm) { 10 | super(and); 11 | _inputs.pop(); 12 | _imm = imm; 13 | } 14 | @Override public String op() { return "andi"; } 15 | @Override public RegMask regmap(int i) { return arm.RMASK; } 16 | @Override public RegMask outregmap() { return arm.WMASK; } 17 | @Override public void encoding( Encoding enc ) { 18 | arm.imm_inst_n(enc,this, in(1), arm.OPI_AND,_imm); 19 | } 20 | // General form: "andi rd = rs1 & imm" 21 | @Override public void asm(CodeGen code, SB sb) { 22 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" & #").p(arm.decodeImm12(_imm)); 23 | } 24 | } -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/NotRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.MachConcreteNode; 6 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 7 | import com.compilerprogramming.ezlang.compiler.node.NotNode; 8 | 9 | public class NotRISC extends MachConcreteNode implements MachNode { 10 | public NotRISC(NotNode not) { super(not); } 11 | @Override public String op() { return "not"; } 12 | @Override public RegMask regmap(int i) { return riscv.RMASK; } 13 | @Override public RegMask outregmap() { return riscv.WMASK; } 14 | @Override public void encoding( Encoding enc ) { 15 | short dst = enc.reg(this ); 16 | short src = enc.reg(in(1)); 17 | enc.add4(riscv.i_type(riscv.OP_IMM, dst, 2, src, 1)); 18 | } 19 | @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)); } 20 | } 21 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/ReadOnlyNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeMemPtr; 5 | 6 | import java.util.BitSet; 7 | 8 | /** 9 | * Cast a pointer to read-only 10 | */ 11 | public class ReadOnlyNode extends Node { 12 | public ReadOnlyNode( Node n ) { super(null,n); } 13 | public ReadOnlyNode( ReadOnlyNode n ) { super(n); } 14 | @Override public String label() { return "ReadOnly"; } 15 | 16 | @Override 17 | public StringBuilder _print1(StringBuilder sb, BitSet visited) { 18 | return in(1)._print0(sb.append("(const)"),visited); 19 | } 20 | @Override public Type compute() { 21 | Type t = in(1)._type; 22 | return t instanceof TypeMemPtr tmp ? tmp.makeRO() : t; 23 | } 24 | 25 | @Override public Node idealize() { 26 | if( in(1)._type instanceof TypeMemPtr tmp && tmp.isFinal() ) 27 | return in(1); 28 | return null; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/SarX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.Utils; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.Node; 6 | 7 | public class SarX86 extends RegX86 { 8 | SarX86( Node add ) { super(add); } 9 | @Override public String op() { return "sar"; } 10 | @Override public String glabel() { return ">>"; } 11 | @Override public RegMask regmap(int i) { 12 | if (i == 1) return x86_64_v2.WMASK; 13 | if (i == 2) return x86_64_v2.RCX_MASK; 14 | throw Utils.TODO(); 15 | } 16 | @Override int opcode() { return 0xD3; } 17 | @Override public void encoding( Encoding enc ) { 18 | short dst = enc.reg(this ); // src1 19 | short src = enc.reg(in(2)); // src2 20 | enc.add1(x86_64_v2.rex(0, dst, 0)); 21 | enc.add1(opcode()); // opcode 22 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 7, dst)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/NegARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.node.MachConcreteNode; 6 | import com.compilerprogramming.ezlang.compiler.util.SB; 7 | 8 | public class NegARM extends MachConcreteNode implements MachNode { 9 | NegARM(Node sub) { 10 | super(sub); 11 | //_inputs.pop(); 12 | } 13 | @Override public String op() { return "neg"; } 14 | @Override public RegMask regmap(int i) { return arm.RMASK; } 15 | @Override public RegMask outregmap() { return arm.WMASK; } 16 | @Override public void encoding( Encoding enc ) { 17 | // reverse subtract with immediate 0 18 | arm.imm_inst(enc,this, in(1), 0b00100110, 0); 19 | } 20 | // General form: "subi rd = rs1 - imm" 21 | @Override public void asm(CodeGen code, SB sb) { 22 | sb.p(code.reg(this)).p(" = -").p(code.reg(in(1))); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/ShlX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.Utils; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.Node; 6 | 7 | public class ShlX86 extends RegX86 { 8 | ShlX86( Node add ) { super(add); } 9 | @Override public String op() { return "shl"; } 10 | @Override public String glabel() { return "<<"; } 11 | @Override public RegMask regmap(int i) { 12 | if (i == 1) return x86_64_v2.WMASK; 13 | if (i == 2) return x86_64_v2.RCX_MASK; 14 | throw Utils.TODO(); 15 | } 16 | @Override int opcode() { return 0xD3; } 17 | @Override public final void encoding( Encoding enc ) { 18 | short dst = enc.reg(this ); // src1 19 | short src = enc.reg(in(2)); // src2 20 | enc.add1(x86_64_v2.rex(0, dst, 0)); 21 | enc.add1(opcode()); // opcode 22 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 4, dst)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/ShrX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.Utils; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.Node; 6 | 7 | public class ShrX86 extends RegX86 { 8 | ShrX86( Node add ) { super(add); } 9 | @Override public String op() { return "shr"; } 10 | @Override public String glabel() { return ">>>"; } 11 | @Override public RegMask regmap(int i) { 12 | if (i == 1) return x86_64_v2.WMASK; 13 | if (i == 2) return x86_64_v2.RCX_MASK; 14 | throw Utils.TODO(); 15 | } 16 | @Override int opcode() { return 0xD3; } 17 | @Override public final void encoding( Encoding enc ) { 18 | short dst = enc.reg(this ); // src1 19 | short src = enc.reg(in(2)); // src2 20 | enc.add1(x86_64_v2.rex(0, dst, 0)); 21 | enc.add1(opcode()); // opcode 22 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 5, dst)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/I2F8ARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class I2F8ARM extends MachConcreteNode implements MachNode { 8 | I2F8ARM(Node i2f8) { super(i2f8); } 9 | @Override public String op() { return "cvt"; } 10 | @Override public RegMask regmap(int i) { return arm.RMASK; } 11 | @Override public RegMask outregmap() { return arm.DMASK; } 12 | @Override public void encoding( Encoding enc ) { 13 | // SCVTF 14 | short self = (short)(enc.reg(this )-arm.D_OFFSET); 15 | short reg1 = enc.reg(in(1)); 16 | int body = arm.float_cast(arm.OP_FLOAT_C, 1, reg1, self); 17 | enc.add4(body); 18 | } 19 | 20 | // General form: "i2f8 (flt)int_value" 21 | @Override public void asm(CodeGen code, SB sb) { 22 | sb.p(code.reg(this)).p(" = ").p("(flt)").p(code.reg(in(1))); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/NegX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class NegX86 extends MachConcreteNode implements MachNode { 8 | NegX86(MinusNode not) { super(not); } 9 | @Override public String op() { return "neg"; } 10 | @Override public RegMask regmap(int i) { return x86_64_v2.RMASK; } 11 | @Override public RegMask outregmap() { return x86_64_v2.RMASK; } 12 | @Override public RegMask killmap() { return x86_64_v2.FLAGS_MASK; } 13 | @Override public int twoAddress() { return 1; } 14 | 15 | @Override public void encoding( Encoding enc ) { 16 | short dst = enc.reg(this ); 17 | enc.add1(x86_64_v2.rex(0, dst, 0)); 18 | enc.add1(0xF7); // opcode 19 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 3, dst)); 20 | } 21 | @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)); } 22 | } 23 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/AndARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.MachConcreteNode; 6 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 7 | import com.compilerprogramming.ezlang.compiler.node.Node; 8 | 9 | public class AndARM extends MachConcreteNode implements MachNode { 10 | AndARM(Node and) { super(and); } 11 | @Override public String op() { return "and"; } 12 | @Override public String glabel() { return "&"; } 13 | @Override public RegMask regmap(int i) { return arm.RMASK; } 14 | @Override public RegMask outregmap() { return arm.WMASK; } 15 | // AND (shifted register) 16 | @Override public void encoding( Encoding enc ) { arm.r_reg(enc,this,arm.OP_AND); } 17 | // General form: #rd = rs1 & rs2 18 | @Override public void asm(CodeGen code, SB sb){ 19 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" & ").p(code.reg(in(2))); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /optvm/src/main/java/com/compilerprogramming/ezlang/compiler/Optimizer.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler; 2 | 3 | import java.util.EnumSet; 4 | 5 | public class Optimizer { 6 | 7 | public void optimize(CompiledFunction function, EnumSet options) { 8 | if (options.contains(Options.OPTIMIZE)) { 9 | if (!function.isSSA) 10 | new EnterSSA(function, options); 11 | if (options.contains(Options.SCCP)) { 12 | new SparseConditionalConstantPropagation().constantPropagation(function).apply(options); 13 | if (new ConstantComparisonPropagation(function).apply(options)) { 14 | // Run SCCP again 15 | // We could repeat this until no further changes occur 16 | new SparseConditionalConstantPropagation().constantPropagation(function).apply(options); 17 | } 18 | } 19 | new ExitSSA(function, options); 20 | } 21 | if (options.contains(Options.REGALLOC)) 22 | new ChaitinGraphColoringRegisterAllocator().assignRegisters(function, 64, options); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/AddIARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class AddIARM extends MachConcreteNode implements MachNode { 8 | final int _imm; 9 | AddIARM(Node add, int imm) { 10 | super(add); 11 | _inputs.pop(); 12 | _imm = imm; 13 | } 14 | @Override public String op() { 15 | return _imm == 1 ? "inc" : (_imm == -1 ? "dec" : "addi"); 16 | } 17 | @Override public RegMask regmap(int i) { return arm.RMASK; } 18 | @Override public RegMask outregmap() { return arm.WMASK; } 19 | //ADD (immediate) 20 | @Override public void encoding( Encoding enc ) { 21 | arm.imm_inst(enc,this, in(1), arm.OPI_ADD,_imm); 22 | } 23 | // General form: "addi rd = rs1 + imm" 24 | @Override public void asm(CodeGen code, SB sb) { 25 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + #").p(_imm); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/MinusFNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeFloat; 5 | 6 | import java.util.BitSet; 7 | 8 | public class MinusFNode extends Node { 9 | public MinusFNode(Node in) { super(null, in); } 10 | 11 | @Override public String label() { return "MinusF"; } 12 | 13 | @Override public String glabel() { return "-"; } 14 | 15 | @Override 16 | public StringBuilder _print1(StringBuilder sb, BitSet visited) { 17 | in(1)._print0(sb.append("(-"), visited); 18 | return sb.append(")"); 19 | } 20 | 21 | @Override 22 | public Type compute() { 23 | if (in(1)._type instanceof TypeFloat i0) 24 | return i0.isConstant() ? TypeFloat.constant(-i0.value()) : i0; 25 | return TypeFloat.F64; 26 | } 27 | 28 | @Override 29 | public Node idealize() { 30 | // -(-x) is x 31 | if( in(1) instanceof MinusFNode minus ) 32 | return minus.in(1); 33 | 34 | return null; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/SubIARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.MachConcreteNode; 5 | 6 | import com.compilerprogramming.ezlang.compiler.node.*; 7 | import com.compilerprogramming.ezlang.compiler.util.SB; 8 | 9 | public class SubIARM extends MachConcreteNode implements MachNode { 10 | final int _imm; 11 | SubIARM(Node sub, int imm) { 12 | super(sub); 13 | _inputs.pop(); 14 | _imm = imm; 15 | } 16 | @Override public String op() { return _imm == -1 ? "dec" : "subi"; } 17 | @Override public RegMask regmap(int i) { return arm.RMASK; } 18 | @Override public RegMask outregmap() { return arm.WMASK; } 19 | 20 | @Override public void encoding( Encoding enc ) { 21 | arm.imm_inst(enc,this, in(1), arm.OPI_SUB,_imm); 22 | } 23 | 24 | // General form: "subi rd = rs1 - imm" 25 | @Override public void asm(CodeGen code, SB sb) { 26 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" - #").p(_imm); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/NotNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.*; 4 | import java.util.BitSet; 5 | 6 | public class NotNode extends Node { 7 | public NotNode(Node in) { super(null, in); } 8 | 9 | @Override public String label() { return "Not"; } 10 | 11 | @Override public String glabel() { return "!"; } 12 | 13 | @Override 14 | public StringBuilder _print1(StringBuilder sb, BitSet visited) { 15 | in(1)._print0(sb.append("(!"), visited); 16 | return sb.append(")"); 17 | } 18 | 19 | @Override 20 | public TypeInteger compute() { 21 | Type t0 = in(1)._type; 22 | if( t0.isHigh() ) return (TypeInteger)TypeInteger.BOOL.dual(); 23 | if( t0 == Type.NIL || t0 == TypeInteger.ZERO ) return TypeInteger.TRUE; 24 | if( t0 instanceof TypeNil tn && tn.notNull() ) return TypeInteger.FALSE; 25 | if( t0 instanceof TypeInteger i && (i._min > 0 || i._max < 0) ) return TypeInteger.FALSE; 26 | return TypeInteger.BOOL; 27 | } 28 | 29 | @Override 30 | public Node idealize() { return null; } 31 | } 32 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/XorIARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.MachConcreteNode; 4 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 5 | 6 | import com.compilerprogramming.ezlang.compiler.codegen.*; 7 | import com.compilerprogramming.ezlang.compiler.node.*; 8 | import com.compilerprogramming.ezlang.compiler.util.SB; 9 | 10 | public class XorIARM extends MachConcreteNode implements MachNode { 11 | final int _imm; 12 | XorIARM(Node xor, int imm) { 13 | super(xor); 14 | _inputs.pop(); 15 | _imm = imm; 16 | } 17 | 18 | @Override public String op() { return "xori"; } 19 | @Override public RegMask regmap(int i) { return arm.RMASK; } 20 | @Override public RegMask outregmap() { return arm.WMASK; } 21 | 22 | // General form: "xori rd = rs1 ^ imm" 23 | @Override public void encoding( Encoding enc ) { arm.imm_inst_n(enc,this, in(1), arm.OPI_XOR,_imm); } 24 | @Override public void asm(CodeGen code, SB sb) { 25 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" ^ #").p(_imm); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/MachConcreteNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.util.Utils; 5 | 6 | import java.util.BitSet; 7 | 8 | // Generic machine-specific class, has a few Node implementations that have to 9 | // exist (abstract) but are not useful past the optimizer. 10 | public abstract class MachConcreteNode extends Node implements MachNode { 11 | 12 | public MachConcreteNode(Node node) { super(node); } 13 | public MachConcreteNode(Node[]nodes) { super(nodes); } 14 | 15 | @Override public String label() { return op(); } 16 | @Override public Type compute () { throw Utils.TODO(); } 17 | @Override public Node idealize() { throw Utils.TODO(); } 18 | 19 | @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { 20 | sb.append("(").append(op()).append(","); 21 | for( int i=1; i 0; 23 | enc.add4(arm.imm_shift(arm.OPI_LSR,_imm, 0b111111, rn,rd)); 24 | } 25 | // General form: "lsri rd = rs1 >>> imm" 26 | @Override public void asm(CodeGen code, SB sb) { 27 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" >>> #").p(_imm); 28 | } 29 | } -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/RoundF32Node.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeFloat; 5 | 6 | import java.util.BitSet; 7 | 8 | public class RoundF32Node extends Node { 9 | public RoundF32Node(Node lhs) { super(null, lhs); } 10 | 11 | @Override public String label() { return "RoundF32"; } 12 | 13 | @Override public String glabel() { return "(f32)"; } 14 | 15 | @Override 16 | public StringBuilder _print1(StringBuilder sb, BitSet visited) { 17 | return in(1)._print0(sb.append("((f32)"), visited).append(")"); 18 | } 19 | 20 | @Override 21 | public Type compute() { 22 | if (in(1)._type instanceof TypeFloat i0 && i0.isConstant() ) 23 | return TypeFloat.constant((float)i0.value()); 24 | return in(1)._type; 25 | } 26 | 27 | @Override 28 | public Node idealize() { 29 | Node lhs = in(1); 30 | Type t1 = lhs._type; 31 | 32 | // RoundF32 of float 33 | if( t1 instanceof TypeFloat tf && tf._sz==32 ) 34 | return lhs; 35 | 36 | return null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/SplitNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.CodeGen; 5 | import com.compilerprogramming.ezlang.compiler.type.Type; 6 | import java.util.BitSet; 7 | 8 | public abstract class SplitNode extends MachConcreteNode { 9 | public final String _kind; // Kind of split 10 | public final byte _round; 11 | public SplitNode(String kind, byte round, Node[] nodes) { super(nodes); _kind = kind; _round = round; } 12 | @Override public String op() { return "mov"; } 13 | @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { 14 | sb.append("mov("); 15 | if( in(1) == null ) sb.append("---"); 16 | else in(1)._print0(sb,visited); 17 | return sb.append(")"); 18 | } 19 | @Override public Type compute() { return in(0)._type; } 20 | @Override public Node idealize() { return null; } 21 | @Override public void asm(CodeGen code, SB sb) { 22 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))); 23 | } 24 | @Override public String comment() { return _kind + " #"+ _round; } 25 | } 26 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/I2F8RISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | // fcvt.d.w 8 | // Converts a 32-bit signed integer, in integer register rs1 into a double-precision floating-point number in floating-point register rd. 9 | public class I2F8RISC extends MachConcreteNode implements MachNode { 10 | I2F8RISC(Node i2f8) {super(i2f8);} 11 | @Override public String op() { return "cvtf"; } 12 | @Override public RegMask regmap(int i) { assert i==1; return riscv.RMASK; } 13 | @Override public RegMask outregmap() { return riscv.FMASK; } 14 | @Override public void encoding( Encoding enc ) { 15 | short dst = (short)(enc.reg(this )-riscv.F_OFFSET); 16 | short src1 = enc.reg(in(1)); 17 | int body = riscv.r_type(riscv.OP_FP,dst,riscv.RM.RNE.ordinal(),src1,0,0x69); 18 | enc.add4(body); 19 | } 20 | @Override public void asm(CodeGen code, SB sb) { 21 | sb.p(code.reg(this)).p(" = ").p("(flt)").p(code.reg(in(1))); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /optvm/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.compilerprogramming.ezlang 8 | compilercraft 9 | 1.0 10 | 11 | optvm 12 | jar 13 | Optimizing VM 14 | 15 | 16 | com.compilerprogramming.ezlang 17 | parser 18 | 1.0 19 | 20 | 21 | com.compilerprogramming.ezlang 22 | types 23 | 1.0 24 | 25 | 26 | com.compilerprogramming.ezlang 27 | semantic 28 | 1.0 29 | 30 | 31 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/ShrNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeInteger; 5 | 6 | public class ShrNode extends ArithNode { 7 | public ShrNode(Node lhs, Node rhs) { super(lhs, rhs); } 8 | 9 | @Override public String label() { return "Shr"; } 10 | @Override public String op() { return ">>>"; } 11 | @Override public String glabel() { return ">>>"; } 12 | 13 | @Override long doOp( long x, long y ) { return x >>> y; } 14 | @Override TypeInteger doOp( TypeInteger x, TypeInteger y ) { 15 | return x == TypeInteger.ZERO ? x : TypeInteger.BOT; 16 | } 17 | 18 | @Override 19 | public Node idealize() { 20 | Node lhs = in(1); 21 | Node rhs = in(2); 22 | Type t2 = rhs._type; 23 | 24 | // Shr of 0. 25 | if( t2.isConstant() && t2 instanceof TypeInteger i && (i.value()&63)==0 ) 26 | return lhs; 27 | 28 | // TODO: x >>> 3 >>> (y ? 1 : 2) ==> x >>> (y ? 4 : 5) 29 | 30 | return super.idealize(); 31 | } 32 | @Override Node copy(Node lhs, Node rhs) { return new ShrNode(lhs,rhs); } 33 | } 34 | -------------------------------------------------------------------------------- /stackvm/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.compilerprogramming.ezlang 8 | compilercraft 9 | 1.0 10 | 11 | stackvm 12 | jar 13 | ByteCode 14 | 15 | 16 | com.compilerprogramming.ezlang 17 | parser 18 | 1.0 19 | 20 | 21 | com.compilerprogramming.ezlang 22 | types 23 | 1.0 24 | 25 | 26 | com.compilerprogramming.ezlang 27 | semantic 28 | 1.0 29 | 30 | 31 | -------------------------------------------------------------------------------- /registervm/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.compilerprogramming.ezlang 8 | compilercraft 9 | 1.0 10 | 11 | registervm 12 | jar 13 | ByteCode 14 | 15 | 16 | com.compilerprogramming.ezlang 17 | parser 18 | 1.0 19 | 20 | 21 | com.compilerprogramming.ezlang 22 | types 23 | 1.0 24 | 25 | 26 | com.compilerprogramming.ezlang 27 | semantic 28 | 1.0 29 | 30 | 31 | -------------------------------------------------------------------------------- /seaofnodes/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.compilerprogramming.ezlang 8 | compilercraft 9 | 1.0 10 | 11 | seaofnodes 12 | jar 13 | SeaOfNodes 14 | 15 | 16 | com.compilerprogramming.ezlang 17 | parser 18 | 1.0 19 | 20 | 21 | com.compilerprogramming.ezlang 22 | types 23 | 1.0 24 | 25 | 26 | com.compilerprogramming.ezlang 27 | semantic 28 | 1.0 29 | 30 | 31 | -------------------------------------------------------------------------------- /optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestChaitinRegAllocator.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class TestChaitinRegAllocator { 7 | 8 | /* Test move does not interfere with uses */ 9 | @Test 10 | public void test4() { 11 | CompiledFunction function = TestInterferenceGraph.buildTest4(); 12 | var graph = new InterferenceGraphBuilder().build(function); 13 | System.out.println(graph.generateDotOutput()); 14 | var edges = graph.getEdges(); 15 | Assert.assertEquals(2, edges.size()); 16 | Assert.assertTrue(edges.contains(new InterferenceGraph.Edge(0, 1))); 17 | Assert.assertTrue(edges.contains(new InterferenceGraph.Edge(0, 2))); 18 | var regAssignments = new ChaitinGraphColoringRegisterAllocator().assignRegisters(function, 64, Options.OPT); 19 | String result = function.toStr(new StringBuilder(), false).toString(); 20 | Assert.assertEquals(""" 21 | L0: 22 | a = 1 23 | b = 2 24 | t = b+a 25 | goto L1 26 | L1: 27 | """, result); 28 | Assert.assertEquals(regAssignments.size(), 3); 29 | Assert.assertEquals(regAssignments.values().stream().sorted().distinct().count(), 2); 30 | } 31 | } -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/RegX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public abstract class RegX86 extends MachConcreteNode { 8 | RegX86( Node add ) { super(add); } 9 | @Override public RegMask regmap(int i) { return x86_64_v2.RMASK; } 10 | @Override public RegMask outregmap() { return x86_64_v2.WMASK; } 11 | @Override public RegMask killmap() { return x86_64_v2.FLAGS_MASK; } 12 | @Override public int twoAddress() { return 1; } 13 | abstract int opcode(); 14 | @Override public void encoding( Encoding enc ) { 15 | // REX.W + 01 /r 16 | short dst = enc.reg(in(1)); // src1 17 | short src = enc.reg(in(2)); // src2 18 | 19 | enc.add1(x86_64_v2.rex(dst, src, 0)); 20 | enc.add1(opcode()); // opcode 21 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src)); 22 | } 23 | // General form: "add dst += src" 24 | @Override public void asm(CodeGen code, SB sb) { 25 | sb.p(code.reg(this)).p(" ").p(glabel()).p("= ").p(code.reg(in(2))); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /parser/src/test/java/com/compilerprogramming/ezlang/parser/TestParser.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.parser; 2 | 3 | import com.compilerprogramming.ezlang.lexer.Lexer; 4 | import org.junit.Test; 5 | 6 | public class TestParser { 7 | 8 | @Test 9 | public void testParse() { 10 | Parser parser = new Parser(); 11 | String src = """ 12 | struct Tree { 13 | var left: Tree? 14 | var right: Tree? 15 | } 16 | struct Test { 17 | var intArray: [Int] 18 | } 19 | struct TreeArray { 20 | var array: [Tree?]? 21 | } 22 | func print(n: Int) {} 23 | func foo(a: Int, b: [Int]) { 24 | while(1) { 25 | if (a > b.length) 26 | break 27 | print(b[a]) 28 | a = a + 1 29 | a = a + 2 30 | } 31 | } 32 | func bar() -> Test { 33 | var v = new Test { intArray = new [Tree] {} } 34 | return v 35 | } 36 | func main() { 37 | var m = 42 38 | var t: Tree 39 | var array = new [Int] {len=10,1,2,3} 40 | array[1] = 42 41 | t.left = null 42 | if (m < 1) 43 | print(1) 44 | else if (m == 5) 45 | print(2) 46 | else 47 | print(3) 48 | } 49 | """; 50 | var program = parser.parse(new Lexer(src)); 51 | System.out.println(program.toString()); 52 | return; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/ToFloatNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeFloat; 5 | import com.compilerprogramming.ezlang.compiler.type.TypeInteger; 6 | 7 | import java.util.BitSet; 8 | 9 | public class ToFloatNode extends Node { 10 | public ToFloatNode(Node lhs) { super(null, lhs); } 11 | 12 | @Override public String label() { return "ToFloat"; } 13 | 14 | @Override public String glabel() { return "(flt)"; } 15 | 16 | @Override 17 | public StringBuilder _print1(StringBuilder sb, BitSet visited) { 18 | return in(1)._print0(sb.append("(flt)"), visited); 19 | } 20 | 21 | @Override 22 | public Type compute() { 23 | if( in(1)._type == Type.NIL ) return TypeFloat.FZERO; 24 | if (in(1)._type instanceof TypeInteger i0 ) { 25 | if( i0.isHigh() ) return TypeFloat.F64.dual(); 26 | if( i0.isConstant() ) 27 | return TypeFloat.constant(i0.value()); 28 | } 29 | return TypeFloat.F64; 30 | } 31 | 32 | @Override public Node idealize() { return null; } 33 | @Override Node copy(Node lhs, Node rhs) { return new ToFloatNode(lhs); } 34 | } 35 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/RegMaskRW.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.codegen; 2 | 3 | // Mutable regmask(writable) 4 | public class RegMaskRW extends RegMask { 5 | public RegMaskRW(long x, long y) { super(x,y); } 6 | // clears bit at position r. Returns true if the mask is still not empty. 7 | public boolean clr(int r) { 8 | if( r < 64 ) _bits0 &= ~(1L<<(r )); 9 | else _bits1 &= ~(1L<<(r-64)); 10 | return _bits0!=0 || _bits1!=0; 11 | } 12 | // sets bit at position r. 13 | public void set(int r) { 14 | if( r < 64 ) _bits0 |= (1L<<(r )); 15 | else _bits1 |= (1L<<(r-64)); 16 | } 17 | @Override RegMaskRW and( RegMask mask ) { 18 | if( mask==null ) return this; 19 | _bits0 &= mask._bits0; 20 | _bits1 &= mask._bits1; 21 | return this; 22 | } 23 | @Override RegMaskRW sub( RegMask mask ) { 24 | if( mask==null ) return this; 25 | _bits0 &= ~mask._bits0; 26 | _bits1 &= ~mask._bits1; 27 | return this; 28 | } 29 | public RegMaskRW or( RegMask mask ) { 30 | if( mask!=null ) { 31 | _bits0 |= mask._bits0; 32 | _bits1 |= mask._bits1; 33 | } 34 | return this; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/MinusNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeInteger; 5 | 6 | import java.util.BitSet; 7 | 8 | public class MinusNode extends Node { 9 | public MinusNode(Node in) { super(null, in); } 10 | 11 | @Override public String label() { return "Minus"; } 12 | 13 | @Override public String glabel() { return "-"; } 14 | 15 | @Override 16 | public StringBuilder _print1(StringBuilder sb, BitSet visited) { 17 | in(1)._print0(sb.append("(-"), visited); 18 | return sb.append(")"); 19 | } 20 | 21 | @Override 22 | public Type compute() { 23 | if( in(1)._type.isHigh() ) return TypeInteger.TOP; 24 | if( in(1)._type instanceof TypeInteger i0 && 25 | i0._min != Long.MIN_VALUE && i0._max != Long.MIN_VALUE ) 26 | return TypeInteger.make(-i0._max,-i0._min); 27 | return TypeInteger.BOT; 28 | } 29 | 30 | @Override 31 | public Node idealize() { 32 | // -(-x) is x 33 | if( in(1) instanceof MinusNode minus ) 34 | return minus.in(1); 35 | 36 | return null; 37 | } 38 | @Override Node copyF() { return new MinusFNode(null); } 39 | } 40 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/I2f8X86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class I2f8X86 extends MachConcreteNode implements MachNode { 8 | I2f8X86(Node i2f8 ) { super(i2f8); } 9 | @Override public String op() { return "cvtf"; } 10 | @Override public RegMask regmap(int i) { assert i==1; return x86_64_v2.WMASK; } 11 | @Override public RegMask outregmap() { return x86_64_v2.XMASK; } 12 | 13 | @Override public void encoding( Encoding enc ) { 14 | // F2 0F 2A /r CVTSI2SD xmm1, r32/m32 15 | short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); 16 | short src = enc.reg(in(1)); 17 | 18 | // Fopcode 19 | enc.add1(0xF2); 20 | // rex prefix must come next (REX.W is not set) 21 | x86_64_v2.rexF(dst, src, 0, true, enc); 22 | 23 | enc.add1(0x0F).add1(0x2A); 24 | 25 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src)); 26 | } 27 | 28 | @Override public void asm(CodeGen code, SB sb) { 29 | sb.p(code.reg(this)).p(" = ").p("(flt)").p(code.reg(in(1))); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /optvm/src/main/java/com/compilerprogramming/ezlang/interpreter/Value.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.interpreter; 2 | 3 | import com.compilerprogramming.ezlang.types.EZType; 4 | 5 | import java.util.ArrayList; 6 | 7 | public class Value { 8 | static public class IntegerValue extends Value { 9 | public IntegerValue(long value) { 10 | this.value = value; 11 | } 12 | public final long value; 13 | } 14 | static public class NullValue extends Value { 15 | public NullValue() {} 16 | } 17 | static public class ArrayValue extends Value { 18 | public final EZType.EZTypeArray arrayType; 19 | public final ArrayList values; 20 | public ArrayValue(EZType.EZTypeArray arrayType, long len, Value initValue) { 21 | this.arrayType = arrayType; 22 | values = new ArrayList<>(); 23 | for (long i = 0; i < len; i++) { 24 | values.add(initValue); 25 | } 26 | } 27 | } 28 | static public class StructValue extends Value { 29 | public final EZType.EZTypeStruct structType; 30 | public final Value[] fields; 31 | public StructValue(EZType.EZTypeStruct structType) { 32 | this.structType = structType; 33 | this.fields = new Value[structType.numFields()]; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/CallRRARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class CallRRARM extends CallNode implements MachNode { 8 | CallRRARM(CallNode call) { super(call); } 9 | @Override public String op() { return "callr"; } 10 | @Override public String label() { return op(); } 11 | @Override public RegMask regmap(int i) { 12 | return i==_inputs._len 13 | ? arm.RMASK // Function call target 14 | : arm.callInMask(tfp(),i,fun()._maxArgSlot); // Normal argument 15 | } 16 | @Override public RegMask outregmap() { return null; } 17 | 18 | @Override public void encoding( Encoding enc ) { 19 | // Needs a register, typically a jump-and-link-register opcode 20 | // blr 21 | short self = enc.reg(this); 22 | enc.add4(arm.blr(arm.OP_CALLRARM, self)); 23 | } 24 | 25 | @Override public void asm(CodeGen code, SB sb) { 26 | sb.p(code.reg(fptr())).p(" "); 27 | for( int i=0; i values; 20 | public ArrayValue(EZType.EZTypeArray arrayType, long len, Value initValue) { 21 | this.arrayType = arrayType; 22 | values = new ArrayList<>(); 23 | for (long i = 0; i < len; i++) { 24 | values.add(initValue); 25 | } 26 | } 27 | } 28 | static public class StructValue extends Value { 29 | public final EZType.EZTypeStruct structType; 30 | public final Value[] fields; 31 | public StructValue(EZType.EZTypeStruct structType) { 32 | this.structType = structType; 33 | this.fields = new Value[structType.numFields()]; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/CallRRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class CallRRISC extends CallNode implements MachNode { 8 | CallRRISC( CallNode call ) { super(call); } 9 | @Override public String op() { return "callr"; } 10 | @Override public String label() { return op(); } 11 | @Override public RegMask regmap(int i) { 12 | return i==_inputs._len-1 13 | ? riscv.RMASK // Function call target 14 | : riscv.callInMask(tfp(),i,fun()._maxArgSlot); // Normal argument 15 | } 16 | @Override public RegMask outregmap() { return null; } 17 | 18 | @Override public void encoding( Encoding enc ) { 19 | short rpc = enc.reg(this); 20 | short src = enc.reg(in(_inputs._len-1)); 21 | int body = riscv.i_type(riscv.OP_JALR, rpc, 0, src, 0); 22 | enc.add4(body); 23 | } 24 | 25 | @Override public void asm(CodeGen code, SB sb) { 26 | sb.p(code.reg(fptr())).p(" "); 27 | for( int i=0; i= riscv.F_OFFSET ? riscv.OP_LOADFP : riscv.OP_LOAD; 21 | if( dst >= riscv.F_OFFSET ) dst -= riscv.F_OFFSET; 22 | enc.add4(riscv.i_type(op, dst, func3(), ptr, _off)); 23 | } 24 | 25 | @Override public void asm(CodeGen code, SB sb) { 26 | sb.p(code.reg(this)).p(","); 27 | asm_address(code,sb); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/SarNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeInteger; 5 | 6 | public class SarNode extends ArithNode { 7 | public SarNode(Node lhs, Node rhs) { super(lhs, rhs); } 8 | 9 | @Override public String label() { return "Sar"; } 10 | @Override public String op() { return ">>"; } 11 | @Override public String glabel() { return ">>"; } 12 | 13 | @Override long doOp( long x, long y ) { return x >> y; } 14 | @Override TypeInteger doOp( TypeInteger x, TypeInteger y ) { 15 | if( y.isConstant() ) { 16 | int log = (int)y.value(); 17 | return TypeInteger.make(-1L<<(63-log),(1L<<(63-log))-1); 18 | } 19 | return TypeInteger.BOT; 20 | } 21 | 22 | @Override 23 | public Node idealize() { 24 | Node lhs = in(1); 25 | Node rhs = in(2); 26 | Type t2 = rhs._type; 27 | 28 | // Sar of 0. 29 | if( t2.isConstant() && t2 instanceof TypeInteger i && (i.value()&63)==0 ) 30 | return lhs; 31 | 32 | // TODO: x >> 3 >> (y ? 1 : 2) ==> x >> (y ? 4 : 5) 33 | 34 | return super.idealize(); 35 | } 36 | @Override Node copy(Node lhs, Node rhs) { return new SarNode(lhs,rhs); } 37 | } 38 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/MulX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class MulX86 extends MachConcreteNode implements MachNode { 8 | MulX86( Node mul ) { super(mul); } 9 | @Override public String op() { return "mul"; } 10 | @Override public RegMask regmap(int i) { assert i==1 || i==2; return x86_64_v2.RMASK; } 11 | @Override public RegMask outregmap() { return x86_64_v2.WMASK; } 12 | @Override public int twoAddress() { return 1; } 13 | @Override public boolean commutes() { return true; } 14 | 15 | @Override public void encoding( Encoding enc ) { 16 | // REX.W + 0F AF /r IMUL r64, r/m64 17 | short dst = enc.reg(this ); // src1 18 | short src = enc.reg(in(2)); // src2 19 | enc.add1(x86_64_v2.rex(dst, src, 0)); 20 | enc.add1(0x0F); // opcode 21 | enc.add1(0xAF); // opcode 22 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src)); 23 | } 24 | 25 | // General form: "mul dst *= src" 26 | @Override public void asm(CodeGen code, SB sb) { 27 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" * ").p(code.reg(in(2))); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/NotARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | 6 | import com.compilerprogramming.ezlang.compiler.node.MachConcreteNode; 7 | import com.compilerprogramming.ezlang.compiler.util.SB; 8 | 9 | public class NotARM extends MachConcreteNode implements MachNode{ 10 | NotARM(NotNode not) {super(not);} 11 | @Override public String op() { return "not"; } 12 | @Override public RegMask regmap(int i) { return arm.RMASK; } 13 | @Override public RegMask outregmap() { return arm.WMASK; } 14 | @Override public RegMask killmap() { return arm.FLAGS_MASK; } 15 | @Override public void encoding( Encoding enc ) { 16 | // subs xzr, rs, #0 17 | // cset rd, eq // Set rd to 1 if rs == 0 (equal), else 0 18 | // subtracting zero from rs will just yield rs, it sets the zero flag and then it's used in cset 19 | short self = enc.reg(this ); 20 | short reg1 = enc.reg(in(1)); 21 | int subs = arm.imm_inst(arm.OP_SUBS, 0, reg1, self); 22 | enc.add4(subs); 23 | int cset = arm.cond_set(arm.OP_CSET, 31, arm.COND.EQ, 63, reg1); 24 | enc.add4(cset); 25 | } 26 | 27 | @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)); } 28 | } 29 | -------------------------------------------------------------------------------- /optvm/src/main/java/com/compilerprogramming/ezlang/compiler/LiveSet.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler; 2 | 3 | import java.util.BitSet; 4 | import java.util.List; 5 | 6 | public class LiveSet extends BitSet { 7 | public LiveSet(int numRegs) { 8 | super(numRegs); 9 | } 10 | public LiveSet dup() { 11 | return (LiveSet) clone(); 12 | } 13 | public void live(Register r) { 14 | set(r.id, true); 15 | } 16 | public void dead(Register r) { 17 | set(r.id, false); 18 | } 19 | public void live(List regs) { 20 | for (Register r : regs) { 21 | live(r); 22 | } 23 | } 24 | public void add(Register r) { 25 | set(r.id, true); 26 | } 27 | public void remove(Register r) { 28 | set(r.id, false); 29 | } 30 | public void remove(List regs) { 31 | for (Register r : regs) { 32 | remove(r); 33 | } 34 | } 35 | public boolean contains(Register r) { 36 | return get(r.id); 37 | } 38 | public LiveSet intersect(LiveSet other) { 39 | and(other); 40 | return this; 41 | } 42 | public LiveSet union(LiveSet other) { 43 | or(other); 44 | return this; 45 | } 46 | /** 47 | * Computes this - other. 48 | */ 49 | public LiveSet subtract(LiveSet other) { 50 | andNot(other); 51 | return this; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/DivFX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class DivFX86 extends MachConcreteNode implements MachNode { 8 | DivFX86( Node divf) { super(divf); } 9 | @Override public String op() { return "divf"; } 10 | @Override public RegMask regmap(int i) { return x86_64_v2.XMASK; } 11 | @Override public RegMask outregmap() { return x86_64_v2.XMASK; } 12 | @Override public int twoAddress() { return 1; } 13 | 14 | @Override public void encoding( Encoding enc ) { 15 | // F2 0F 5E /r DIVSD xmm1, xmm2/m64 16 | short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); 17 | short src = (short)(enc.reg(in(2)) - x86_64_v2.XMM_OFFSET); 18 | 19 | // Fopcode 20 | enc.add1(0xF2); 21 | // rex prefix must come next (REX.W is not set) 22 | x86_64_v2.rexF(dst, src, 0, false, enc); 23 | 24 | enc.add1(0x0F).add1(0x5E); 25 | 26 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src)); 27 | } 28 | 29 | 30 | // General form: "divf dst /= src" 31 | @Override public void asm(CodeGen code, SB sb) { 32 | sb.p(code.reg(this)).p(" /= ").p(code.reg(in(2))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/AsrIARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.CodeGen; 5 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 6 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 7 | import com.compilerprogramming.ezlang.compiler.node.MachConcreteNode; 8 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 9 | import com.compilerprogramming.ezlang.compiler.node.Node; 10 | 11 | public class AsrIARM extends MachConcreteNode implements MachNode { 12 | final int _imm; 13 | AsrIARM(Node asr, int imm) { 14 | super(asr); 15 | _inputs.pop(); 16 | _imm = imm; 17 | } 18 | @Override public String op() { return "asri"; } 19 | @Override public RegMask regmap(int i) { return arm.RMASK; } 20 | @Override public RegMask outregmap() { return arm.WMASK; } 21 | @Override public void encoding( Encoding enc ) { 22 | short rd = enc.reg(this); 23 | short rn = enc.reg(in(1)); 24 | assert _imm > 0; 25 | enc.add4(arm.imm_shift(arm.OPI_ASR,_imm, 0b111111, rn, rd)); 26 | } 27 | // General form: "asri rd = rs1 >> imm" 28 | @Override public void asm(CodeGen code, SB sb) { 29 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" >> #").p(_imm); 30 | } 31 | } -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/CmpFX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class CmpFX86 extends MachConcreteNode implements MachNode { 8 | CmpFX86( Node cmp ) { super(cmp); } 9 | @Override public String op() { return "cmpf"; } 10 | @Override public RegMask regmap(int i) { return x86_64_v2.XMASK; } 11 | @Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; } 12 | 13 | @Override public void encoding( Encoding enc ) { 14 | // UCOMISD 15 | short src1 = (short)(enc.reg(in(1)) - x86_64_v2.XMM_OFFSET); 16 | short src2 = (short)(enc.reg(in(2)) - x86_64_v2.XMM_OFFSET); 17 | // float opcode 18 | enc.add1(0x66); 19 | // rex prefix must come next (REX.W is not set) 20 | x86_64_v2.rexF(src1, src2, 0, false, enc); 21 | 22 | enc.add1(0x0F).add1(0x2E); 23 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, src1, src2)); 24 | } 25 | 26 | // General form: "cmp src1,src2" 27 | @Override public void asm(CodeGen code, SB sb) { 28 | String dst = code.reg(this); 29 | if( dst!="flags" ) sb.p(dst).p(" = "); 30 | sb.p(code.reg(in(1))).p(", ").p(code.reg(in(2))); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/SubFX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class SubFX86 extends MachConcreteNode implements MachNode { 8 | SubFX86( Node subf) { super(subf); } 9 | @Override public String op() { return "subf"; } 10 | @Override public RegMask regmap(int i) { assert i==1 || i==2; return x86_64_v2.XMASK; } 11 | @Override public RegMask outregmap() { return x86_64_v2.XMASK; } 12 | @Override public int twoAddress() { return 1; } 13 | 14 | @Override public void encoding( Encoding enc ) { 15 | // F2 0F 5C /r SUBSD xmm1, xmm2/m64 16 | short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); 17 | short src = (short)(enc.reg(in(2)) - x86_64_v2.XMM_OFFSET); 18 | // Fopcode 19 | enc.add1(0xF2); 20 | // rex prefix must come next (REX.W is not set) 21 | x86_64_v2.rexF(dst, src, 0, false, enc); 22 | 23 | enc.add1(0x0F).add1(0x5C); 24 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src)); 25 | } 26 | 27 | // General form: "subf dst -= src" 28 | @Override public void asm(CodeGen code, SB sb) { 29 | sb.p(code.reg(this)).p(" -= ").p(code.reg(in(2))); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/AddMemX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class AddMemX86 extends MemOpX86 { 8 | AddMemX86( AddNode add, LoadNode ld , Node base, Node idx, int off, int scale, int imm, Node val ) { 9 | super(add,ld, base, idx, off, scale, imm, val ); 10 | } 11 | @Override public String op() { return "add"+_sz; } 12 | @Override public RegMask outregmap() { return x86_64_v2.WMASK; } 13 | @Override public int twoAddress() { return 4; } 14 | @Override public void encoding( Encoding enc ) { 15 | // add something to register from memory 16 | // add eax,DWORD PTR [rdi+0xc] 17 | // REX.W + 03 /r ADD r64, r/m64 18 | short dst = enc.reg(this ); 19 | short ptr = enc.reg(ptr()); 20 | short idx = enc.reg(idx()); 21 | 22 | enc.add1(x86_64_v2.rex(dst, ptr, idx)); 23 | // opcode 24 | enc.add1(0x03); 25 | 26 | x86_64_v2.indirectAdr(_scale, idx, ptr, _off, dst, enc); 27 | } 28 | 29 | // General form: "add dst += [base + idx<<2 + 12]" 30 | @Override public void asm(CodeGen code, SB sb) { 31 | sb.p(code.reg(this)).p(" += "); 32 | asm_address(code,sb); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/CallRX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.CallNode; 6 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 7 | 8 | public class CallRX86 extends CallNode implements MachNode { 9 | CallRX86( CallNode call ) { super(call); } 10 | @Override public String op() { return "callr"; } 11 | @Override public String label() { return op(); } 12 | @Override public RegMask regmap(int i) { 13 | return i==_inputs._len 14 | ? x86_64_v2.WMASK // Function call target 15 | : x86_64_v2.callInMask(tfp(),i,fun()._maxArgSlot); // Normal argument 16 | } 17 | @Override public RegMask outregmap() { return null; } 18 | @Override public void encoding( Encoding enc ) { 19 | // FF /2 CALL r/m64 20 | // calls the function in the register 21 | short src = enc.reg(fptr()); 22 | enc.add1(0xFF); 23 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.INDIRECT,2,src)); 24 | } 25 | 26 | @Override public void asm(CodeGen code, SB sb) { 27 | sb.p(code.reg(fptr())).p(" "); 28 | for( int i=0; i>12) & 0xFFFFF; 23 | short dst = enc.reg(this); 24 | int lui = riscv.u_type(riscv.OP_LUI, dst, imm20); 25 | enc.add4(lui); 26 | } 27 | 28 | @Override public void asm(CodeGen code, SB sb) { 29 | String reg = code.reg(this); 30 | sb.p(reg).p(" = #").hex4((int)(((TypeInteger)_con).value())); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /types/src/main/java/com/compilerprogramming/ezlang/types/Scope.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.types; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedHashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public class Scope { 9 | 10 | public final Map bindings = new LinkedHashMap<>(); 11 | public final Scope parent; 12 | public final List children = new ArrayList<>(); 13 | 14 | // values assigned by compiler 15 | public int maxReg; 16 | public final boolean isFunctionParameterScope; 17 | 18 | public Scope(Scope parent, boolean isFunctionParameterScope) { 19 | this.parent = parent; 20 | this.isFunctionParameterScope = isFunctionParameterScope; 21 | if (parent != null) 22 | parent.children.add(this); 23 | } 24 | 25 | public Scope(Scope parent) { 26 | this(parent, false); 27 | } 28 | 29 | public Symbol lookup(String name) { 30 | Symbol symbol = bindings.get(name); 31 | if (symbol == null && parent != null) 32 | symbol = parent.lookup(name); 33 | return symbol; 34 | } 35 | 36 | public Symbol localLookup(String name) { 37 | return bindings.get(name); 38 | } 39 | 40 | public Symbol install(String name, Symbol symbol) { 41 | bindings.put(name, symbol); 42 | return symbol; 43 | } 44 | 45 | public List getLocalSymbols() { 46 | return new ArrayList<>(bindings.values()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/AddFX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class AddFX86 extends MachConcreteNode implements MachNode { 8 | AddFX86( Node addf ) { super(addf); } 9 | @Override public String op() { return "addf"; } 10 | @Override public RegMask regmap(int i) { assert i==1 || i==2; return x86_64_v2.XMASK; } 11 | @Override public RegMask outregmap() { return x86_64_v2.XMASK; } 12 | @Override public int twoAddress() { return 1; } 13 | @Override public boolean commutes() { return true; } 14 | 15 | @Override public void encoding( Encoding enc ) { 16 | // F2 0F 58 /r ADDSD xmm1, xmm2/m64 17 | short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); 18 | short src = (short)(enc.reg(in(2)) - x86_64_v2.XMM_OFFSET); 19 | // Fopcode 20 | enc.add1(0xF2); 21 | // rex prefix must come next (REX.W is not set) 22 | x86_64_v2.rexF(dst, src, 0, false, enc); 23 | 24 | enc.add1(0x0F).add1(0x58); 25 | 26 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src)); 27 | } 28 | 29 | // General form: "addf dst += src" 30 | @Override public void asm(CodeGen code, SB sb) { 31 | sb.p(code.reg(this)).p(" += ").p(code.reg(in(2))); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/FunX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.CodeGen; 4 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 5 | import com.compilerprogramming.ezlang.compiler.node.FunNode; 6 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 7 | 8 | public class FunX86 extends FunNode implements MachNode { 9 | FunX86( FunNode fun ) { super(fun); } 10 | @Override public void postSelect(CodeGen code) { 11 | super.postSelect(code); 12 | // One more for RPC pre-pushed; X86 special 13 | _maxArgSlot++; 14 | } 15 | 16 | @Override public void computeFrameAdjust(CodeGen code, int maxReg) { 17 | super.computeFrameAdjust(code,maxReg); 18 | // Alignment, but off by RPC 19 | if( _hasCalls ) // If non-leaf, pad to 16b 20 | _frameAdjust = ((_frameAdjust+8+8) & -16)-8; 21 | } 22 | 23 | @Override public void encoding( Encoding enc ) { 24 | int sz = _frameAdjust; 25 | if( sz == 0 ) return; // Skip if no frame adjust 26 | // opcode: 0x83, addi rsp with immediate 8 27 | enc.add1( x86_64_v2.REX_W ).add1( x86_64_v2.imm8(sz) ? 0x83 : 0x81 ); 28 | enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0b101, x86_64_v2.RSP) ); 29 | if( x86_64_v2.imm8(sz) ) enc.add1(sz); 30 | else enc.add4(sz); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/AddFNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeFloat; 5 | 6 | import java.util.BitSet; 7 | 8 | public class AddFNode extends Node { 9 | public AddFNode(Node lhs, Node rhs) { super(null, lhs, rhs); } 10 | 11 | @Override public String label() { return "AddF"; } 12 | 13 | @Override public String glabel() { return "+"; } 14 | 15 | @Override 16 | public StringBuilder _print1(StringBuilder sb, BitSet visited) { 17 | in(1)._print0(sb.append("("), visited); 18 | in(2)._print0(sb.append("+"), visited); 19 | return sb.append(")"); 20 | } 21 | 22 | @Override 23 | public Type compute() { 24 | if (in(1)._type instanceof TypeFloat i0 && 25 | in(2)._type instanceof TypeFloat i1) { 26 | if (i0.isConstant() && i1.isConstant()) 27 | return TypeFloat.constant(i0.value()+i1.value()); 28 | } 29 | return in(1)._type.meet(in(2)._type); 30 | } 31 | 32 | @Override 33 | public Node idealize() { 34 | Node lhs = in(1); 35 | Type t2 = in(2)._type; 36 | 37 | // Add of 0. 38 | if ( t2.isConstant() && t2 instanceof TypeFloat i && i.value()==0 ) 39 | return lhs; 40 | 41 | return null; 42 | } 43 | @Override Node copy(Node lhs, Node rhs) { return new AddFNode(lhs,rhs); } 44 | } 45 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/DivFNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeFloat; 5 | 6 | import java.util.BitSet; 7 | 8 | public class DivFNode extends Node { 9 | public DivFNode(Node lhs, Node rhs) { super(null, lhs, rhs); } 10 | 11 | @Override public String label() { return "DivF"; } 12 | 13 | @Override public String glabel() { return "/"; } 14 | 15 | @Override 16 | public StringBuilder _print1(StringBuilder sb, BitSet visited) { 17 | in(1)._print0(sb.append("("), visited); 18 | in(2)._print0(sb.append("/"), visited); 19 | return sb.append(")"); 20 | } 21 | 22 | @Override 23 | public Type compute() { 24 | if (in(1)._type instanceof TypeFloat i0 && 25 | in(2)._type instanceof TypeFloat i1) { 26 | if (i0.isConstant() && i1.isConstant()) 27 | return TypeFloat.constant(i0.value()/i1.value()); 28 | } 29 | return in(1)._type.meet(in(2)._type); 30 | } 31 | 32 | @Override 33 | public Node idealize() { 34 | // Div of constant 35 | if( in(2)._type instanceof TypeFloat f && f.isConstant() ) 36 | return new MulFNode(in(1),new ConstantNode(TypeFloat.constant(1.0/f.value())).peephole()); 37 | 38 | return null; 39 | } 40 | @Override Node copy(Node lhs, Node rhs) { return new DivFNode(lhs,rhs); } 41 | } 42 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/SubFNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeFloat; 5 | 6 | import java.util.BitSet; 7 | 8 | public class SubFNode extends Node { 9 | public SubFNode(Node lhs, Node rhs) { super(null, lhs, rhs); } 10 | 11 | @Override public String label() { return "SubF"; } 12 | 13 | @Override public String glabel() { return "-"; } 14 | 15 | @Override 16 | public StringBuilder _print1(StringBuilder sb, BitSet visited) { 17 | in(1)._print0(sb.append("("), visited); 18 | in(2)._print0(sb.append("-"), visited); 19 | return sb.append(")"); 20 | } 21 | 22 | @Override 23 | public Type compute() { 24 | if (in(1)._type instanceof TypeFloat i0 && 25 | in(2)._type instanceof TypeFloat i1) { 26 | if (i0.isConstant() && i1.isConstant()) 27 | return TypeFloat.constant(i0.value()-i1.value()); 28 | } 29 | return in(1)._type.meet(in(2)._type); 30 | } 31 | 32 | @Override 33 | public Node idealize() { 34 | Node lhs = in(1); 35 | Type t2 = in(2)._type; 36 | 37 | // Sub of 0. 38 | if ( t2.isConstant() && t2 instanceof TypeFloat i && i.value()==0 ) 39 | return lhs; 40 | 41 | return null; 42 | } 43 | @Override Node copy(Node lhs, Node rhs) { return new SubFNode(lhs,rhs); } 44 | } 45 | -------------------------------------------------------------------------------- /lexer/src/main/java/com/compilerprogramming/ezlang/lexer/Token.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.lexer; 2 | 3 | public class Token { 4 | 5 | public enum Kind { 6 | IDENT, 7 | NUM, 8 | PUNCT, 9 | EOZ // Special kind to signal end of file 10 | } 11 | 12 | public final Kind kind; 13 | /** 14 | * String representation of a token - always 15 | * populated 16 | */ 17 | public final String str; 18 | /** 19 | * The parsed number value, only populated for Kind.NUM 20 | */ 21 | public final Number num; 22 | public final int lineNumber; 23 | 24 | public Token(Kind kind, String str, Number num, int lineNumber) { 25 | this.kind = kind; 26 | this.str = str; 27 | this.num = num; 28 | this.lineNumber = lineNumber; 29 | } 30 | 31 | public static Token newIdent(String str, int lineNumber) { 32 | return new Token(Kind.IDENT, str.intern(), null, lineNumber); 33 | } 34 | public static Token newNum(Number num, String str, int lineNumber) { 35 | return new Token(Kind.NUM, str, num, lineNumber); 36 | } 37 | public static Token newPunct(String str, int lineNumber) { 38 | return new Token(Kind.PUNCT, str.intern(), null, lineNumber); 39 | } 40 | 41 | /** 42 | * Special token that indicates that source has been exhausted 43 | */ 44 | public static Token EOF = new Token(Kind.EOZ, "", null, 0); 45 | 46 | public String toString() { 47 | return str; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /types/src/main/java/com/compilerprogramming/ezlang/types/Symbol.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.types; 2 | 3 | /** 4 | * A symbol is something that has a name and a type. 5 | */ 6 | public abstract class Symbol { 7 | 8 | public final String name; 9 | public EZType type; 10 | 11 | protected Symbol(String name, EZType type) { 12 | this.name = name; 13 | this.type = type; 14 | } 15 | 16 | public static class TypeSymbol extends Symbol { 17 | public TypeSymbol(String name, EZType type) { 18 | super(name, type); 19 | } 20 | } 21 | 22 | public static class FunctionTypeSymbol extends Symbol { 23 | public final Object functionDecl; 24 | public FunctionTypeSymbol(String name, EZType.EZTypeFunction type, Object functionDecl) { 25 | super(name, type); 26 | this.functionDecl = functionDecl; 27 | } 28 | public Object code() { 29 | EZType.EZTypeFunction function = (EZType.EZTypeFunction) type; 30 | return function.code; 31 | } 32 | } 33 | 34 | public static class VarSymbol extends Symbol { 35 | // Values assigned by bytecode compiler 36 | public int regNumber; 37 | public VarSymbol(String name, EZType type) { 38 | super(name, type); 39 | } 40 | } 41 | 42 | public static class ParameterSymbol extends VarSymbol { 43 | public ParameterSymbol(String name, EZType type) { 44 | super(name, type); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/DivX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class DivX86 extends MachConcreteNode implements MachNode { 8 | DivX86( Node div ) { super(div); } 9 | @Override public String op() { return "div"; } 10 | @Override public RegMask regmap(int i) { 11 | return (i==1) ? x86_64_v2.RAX_MASK : x86_64_v2.DIV_MASK; 12 | } 13 | @Override public RegMask outregmap() { return x86_64_v2.RAX_MASK; } 14 | @Override public RegMask killmap() { return x86_64_v2.RDX_MASK; } 15 | 16 | @Override public void encoding( Encoding enc ) { 17 | // REX.W + F7 /7 IDIV r/m64 18 | short src = enc.reg(in(2)); 19 | // sign extend rax before 128/64 bits division 20 | // sign extend rax to rdx:rax 21 | enc.add1(x86_64_v2.REX_W); 22 | enc.add1(0x99); 23 | enc.add1(x86_64_v2.rex(0, src, 0)); 24 | // divide 25 | enc.add1(0xF7); // opcode 26 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0x07, src)); 27 | } 28 | // General form: "div dst /= src" 29 | @Override public void asm(CodeGen code, SB sb) { 30 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" / ").p(code.reg(in(2))); 31 | } 32 | @Override public String comment() { return "kill rdx"; } 33 | } 34 | -------------------------------------------------------------------------------- /stackvm/src/main/java/com/compilerprogramming/ezlang/compiler/BasicBlock.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler; 2 | 3 | import java.util.ArrayList; 4 | import java.util.BitSet; 5 | import java.util.List; 6 | 7 | public class BasicBlock { 8 | public final int bid; 9 | public final boolean loopHead; 10 | public final List successors = new ArrayList<>(); // successors 11 | public final List predecessors = new ArrayList<>(); 12 | public final List instructions = new ArrayList<>(); 13 | 14 | public BasicBlock(int bid, boolean loopHead) { 15 | this.bid = bid; 16 | this.loopHead = loopHead; 17 | } 18 | public BasicBlock(int bid) { 19 | this(bid, false); 20 | } 21 | public void add(Instruction instruction) { 22 | instructions.add(instruction); 23 | } 24 | public void addSuccessor(BasicBlock successor) { 25 | successors.add(successor); 26 | successor.predecessors.add(this); 27 | } 28 | 29 | public static StringBuilder toStr(StringBuilder sb, BasicBlock bb, BitSet visited) 30 | { 31 | if (visited.get(bb.bid)) 32 | return sb; 33 | visited.set(bb.bid); 34 | sb.append("L").append(bb.bid).append(":\n"); 35 | for (Instruction n: bb.instructions) { 36 | sb.append("\t"); 37 | n.toStr(sb).append("\n"); 38 | } 39 | for (BasicBlock succ: bb.successors) { 40 | toStr(sb, succ, visited); 41 | } 42 | return sb; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /registervm/src/main/java/com/compilerprogramming/ezlang/compiler/BasicBlock.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler; 2 | 3 | import java.util.ArrayList; 4 | import java.util.BitSet; 5 | import java.util.List; 6 | 7 | public class BasicBlock { 8 | public final int bid; 9 | public final boolean loopHead; 10 | public final List successors = new ArrayList<>(); // successors 11 | public final List predecessors = new ArrayList<>(); 12 | public final List instructions = new ArrayList<>(); 13 | 14 | public BasicBlock(int bid, boolean loopHead) { 15 | this.bid = bid; 16 | this.loopHead = loopHead; 17 | } 18 | public BasicBlock(int bid) { 19 | this(bid, false); 20 | } 21 | public void add(Instruction instruction) { 22 | instructions.add(instruction); 23 | } 24 | public void addSuccessor(BasicBlock successor) { 25 | successors.add(successor); 26 | successor.predecessors.add(this); 27 | } 28 | 29 | public static StringBuilder toStr(StringBuilder sb, BasicBlock bb, BitSet visited) 30 | { 31 | if (visited.get(bb.bid)) 32 | return sb; 33 | visited.set(bb.bid); 34 | sb.append("L").append(bb.bid).append(":\n"); 35 | for (Instruction n: bb.instructions) { 36 | sb.append(" "); 37 | n.toStr(sb).append("\n"); 38 | } 39 | for (BasicBlock succ: bb.successors) { 40 | toStr(sb, succ, visited); 41 | } 42 | return sb; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/SubNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.TypeInteger; 4 | 5 | public class SubNode extends ArithNode { 6 | public SubNode(Node lhs, Node rhs) { super(lhs, rhs); } 7 | 8 | @Override public String label() { return "Sub"; } 9 | @Override public String op() { return "-"; } 10 | 11 | @Override long doOp( long x, long y ) { return x - y; } 12 | @Override TypeInteger doOp(TypeInteger x, TypeInteger y) { 13 | // Sub of same is 0 14 | if( in(1)==in(2) ) 15 | return TypeInteger.ZERO; 16 | // Fold ranges like {2-3} - {0-1} into {1-3}. 17 | if( !AddNode.overflow(x._min,-y._max) && 18 | !AddNode.overflow(x._max,-y._min) && 19 | y._min != Long.MIN_VALUE ) 20 | return TypeInteger.make(x._min-y._max,x._max-y._min); 21 | 22 | return TypeInteger.BOT; 23 | } 24 | 25 | @Override 26 | public Node idealize() { 27 | // x - (-y) is x+y 28 | if( in(2) instanceof MinusNode minus ) 29 | return new AddNode(in(1),minus.in(1)); 30 | 31 | // (-x) - y is -(x+y) 32 | if( in(1) instanceof MinusNode minus ) 33 | return new MinusNode(new AddNode(minus.in(1),in(2)).peephole()); 34 | 35 | return super.idealize(); 36 | } 37 | 38 | @Override Node copy(Node lhs, Node rhs) { return new SubNode(lhs,rhs); } 39 | @Override Node copyF() { return new SubFNode(null,null); } 40 | } 41 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/NewARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | import com.compilerprogramming.ezlang.compiler.util.Utils; 7 | 8 | public class NewARM extends NewNode implements MachNode, RIPRelSize { 9 | // A pre-zeroed chunk of memory. 10 | NewARM(NewNode nnn) { super(nnn); } 11 | @Override public void encoding( Encoding enc ) { 12 | // BL(branch with link) 13 | enc.external(this,"calloc"). 14 | add4(arm.mov(arm.OP_MOVZ, 0, 1, 0)). // movz x0,#1 15 | add4(arm.b(arm.OP_CALL, 0)); 16 | } 17 | 18 | // Patch is for running "new" in a JIT. 19 | // Delta is from opcode start 20 | @Override public byte encSize(int delta) { return 4*2; } 21 | 22 | // Patch is for running "new" in a JIT. 23 | // Delta is from opcode start 24 | @Override public void patch(Encoding enc, int opStart, int opLen, int delta ) { 25 | // Negative patches are JIT emulator targets. 26 | if( opStart+delta < 0 ) { 27 | enc.patch4(opStart+4, arm.b_calloc(arm.OP_CALL, delta-4)); 28 | } else { 29 | throw Utils.TODO(); 30 | } 31 | } 32 | // General form: "alloc #bytes PC" 33 | @Override public void asm(CodeGen code, SB sb) { 34 | sb.p("ldi x0=#1\n"); 35 | sb.p("call #calloc"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/CmpX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | public class CmpX86 extends MachConcreteNode implements MachNode { 8 | CmpX86( Node add ) { super(add); } 9 | @Override public String op() { return "cmp"; } 10 | @Override public RegMask regmap(int i) { return x86_64_v2.RMASK; } 11 | @Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; } 12 | // This one is marginal: cloning a Cmp[reg,reg] means stretching the 13 | // lifetimes of 2 normal registers in exchange for shortening a flags 14 | // register lifetime. Spilling flags is (probably) relatively expensive 15 | // compared to some normal registers - and those normal registers might not 16 | // be spilling! 17 | @Override public boolean isClone() { return true; } 18 | 19 | @Override public void encoding( Encoding enc ) { 20 | short dst = enc.reg(in(1)); 21 | short src = enc.reg(in(2)); 22 | 23 | enc.add1(x86_64_v2.rex(dst, src, 0)); 24 | enc.add1(0x3B); 25 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src)); 26 | } 27 | @Override public void asm(CodeGen code, SB sb) { 28 | String dst = code.reg(this); 29 | if( dst!="flags" ) sb.p(dst).p(" = "); 30 | sb.p(code.reg(in(1))).p(", ").p(code.reg(in(2))); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/LslIARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.CodeGen; 5 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 6 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 7 | import com.compilerprogramming.ezlang.compiler.node.MachConcreteNode; 8 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 9 | import com.compilerprogramming.ezlang.compiler.node.Node; 10 | 11 | public class LslIARM extends MachConcreteNode implements MachNode { 12 | final int _imm; 13 | LslIARM(Node lsl, int imm) { 14 | super(lsl); 15 | _inputs.pop(); 16 | _imm = imm; 17 | } 18 | @Override public String op() { return "lsli"; } 19 | @Override public RegMask regmap(int i) { return arm.RMASK; } 20 | @Override public RegMask outregmap() { return arm.WMASK; } 21 | @Override public void encoding( Encoding enc ) { 22 | short rd = enc.reg(this); 23 | short rn = enc.reg(in(1)); 24 | assert _imm > 0; 25 | // UBFM , , #(- MOD 64), #(63-) 26 | // immr must be (- MOD 64) = 64 - shift 27 | enc.add4(arm.imm_shift(arm.OPI_LSL, 64 - _imm, (64 - _imm) - 1, rn, rd)); 28 | } 29 | // General form: "lsli rd = rs1 << imm" 30 | @Override public void asm(CodeGen code, SB sb) { 31 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" << #").p(_imm); 32 | } 33 | } -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/ShrIX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.node.Node; 4 | 5 | import com.compilerprogramming.ezlang.compiler.codegen.*; 6 | import com.compilerprogramming.ezlang.compiler.node.*; 7 | import com.compilerprogramming.ezlang.compiler.util.SB; 8 | 9 | public class ShrIX86 extends MachConcreteNode implements MachNode { 10 | final int _imm; 11 | ShrIX86( Node shri, int imm ) { super(shri); assert x86_64_v2.imm8(imm); _inputs.pop(); _imm = imm; } 12 | @Override public String op() { return "shri"; } 13 | @Override public String glabel() { return ">>>"; } 14 | int opcode() { return 0xC1; } 15 | int mod() { return 5; } 16 | 17 | @Override public RegMask regmap(int i) { return x86_64_v2.RMASK; } 18 | @Override public RegMask outregmap() { return x86_64_v2.WMASK; } 19 | @Override public int twoAddress() { return 1; } 20 | 21 | @Override public void encoding(Encoding enc) { 22 | short dst = enc.reg(this); // Also src1 23 | enc.add1(x86_64_v2.rex(0, dst, 0)); 24 | enc.add1( opcode()); 25 | 26 | enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, mod(), dst) ); 27 | 28 | // immediate(4 bytes) 32 bits or (1 byte)8 bits 29 | if( x86_64_v2.imm8(_imm) ) enc.add1(_imm); 30 | else enc.add4(_imm); 31 | } 32 | @Override public void asm(CodeGen code, SB sb) { 33 | sb.p(code.reg(this)).p(" ").p(glabel()).p("= #").p(_imm); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/CmpIARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.codegen.*; 4 | import com.compilerprogramming.ezlang.compiler.node.*; 5 | import com.compilerprogramming.ezlang.compiler.util.SB; 6 | 7 | // Compare with immediate. 8 | // CMP (immediate) - SUBS 9 | public class CmpIARM extends MachConcreteNode implements MachNode { 10 | final int _imm; 11 | final String _bop; 12 | CmpIARM(BoolNode bool, int imm) { 13 | super(bool); 14 | _inputs.pop(); 15 | _bop = bool.op(); 16 | _imm = imm; 17 | } 18 | CmpIARM( CmpIARM cmp ) { 19 | super((Node)null); 20 | addDef(null); 21 | addDef(cmp.in(1)); 22 | _bop = cmp._bop; 23 | _imm = cmp._imm; 24 | } 25 | @Override public String op() { return _imm==0 ? "test" : "cmp"; } 26 | @Override public RegMask regmap(int i) { return arm.RMASK; } 27 | @Override public RegMask outregmap() { return arm.FLAGS_MASK; } 28 | @Override public boolean isClone() { return true; } 29 | @Override public Node copy() { return new CmpIARM(this); } 30 | 31 | @Override public void encoding( Encoding enc ) { arm.imm_inst_subs(enc,in(1),in(1), arm.OPI_CMP,_imm); } 32 | 33 | // General form: "cmp rs1, 1" 34 | @Override public void asm(CodeGen code, SB sb) { 35 | String dst = code.reg(this); 36 | if( dst!="flags" ) sb.p(dst).p(" = "); 37 | sb.p(code.reg(in(1))); 38 | if( _imm != 0 ) sb.p(", #").p(_imm); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/riscv/SetFRISC.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.riscv; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.BoolNode; 6 | import com.compilerprogramming.ezlang.compiler.node.MachConcreteNode; 7 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 8 | 9 | // corresponds to feq.d = equal 10 | // fle.d = less than or equal 11 | // flt.d = less than 12 | public class SetFRISC extends MachConcreteNode implements MachNode { 13 | final String _bop; // One of <,<=,== 14 | SetFRISC( BoolNode bool ) { 15 | super(bool); 16 | assert bool.isFloat(); 17 | _bop = bool.op(); 18 | } 19 | @Override public String op() { return "set"+_bop; } 20 | @Override public RegMask regmap(int i) { return riscv.FMASK; } 21 | @Override public RegMask outregmap() { return riscv.WMASK; } 22 | @Override public void encoding( Encoding enc ) { 23 | short dst = enc.reg(this ); 24 | short src1 = (short)(enc.reg(in(1))-riscv.F_OFFSET); 25 | short src2 = (short)(enc.reg(in(2))-riscv.F_OFFSET); 26 | int body = riscv.r_type(riscv.OP_FP,dst,riscv.fsetop(_bop),src1,src2,0b1010001/*FCMP*/); 27 | enc.add4(body); 28 | } 29 | 30 | @Override public void asm(CodeGen code, SB sb) { 31 | sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" ").p(_bop).p(" ").p(code.reg(in(2))); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/StructNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.type.*; 5 | import java.util.BitSet; 6 | 7 | /** 8 | * Build a compound object 9 | */ 10 | public class StructNode extends Node { 11 | 12 | public TypeStruct _ts; 13 | 14 | @Override public String label() { return _ts==null ? "STRUCT?" : _ts.str(); } 15 | 16 | @Override 17 | public StringBuilder _print1(StringBuilder sb, BitSet visited) { 18 | if( _ts==null ) return sb.append("STRUCT?"); 19 | sb.append(_ts._name).append(" {"); 20 | for( int i=0; i[Int] 2 | { 3 | // The main Sieve array 4 | var ary = new [Int]{len=N,value=0} 5 | // The primes less than N 6 | var primes = new [Int]{len=N/2,value=0} 7 | // Number of primes so far, searching at index p 8 | var nprimes = 0 9 | var p=2 10 | // Find primes while p^2 < N 11 | while( p*p < N ) { 12 | // skip marked non-primes 13 | while( ary[p] ) { 14 | p = p + 1 15 | } 16 | // p is now a prime 17 | primes[nprimes] = p 18 | nprimes = nprimes+1 19 | // Mark out the rest non-primes 20 | var i = p + p 21 | while( i < N ) { 22 | ary[i] = 1 23 | i = i + p 24 | } 25 | p = p + 1 26 | } 27 | 28 | // Now just collect the remaining primes, no more marking 29 | while ( p < N ) { 30 | if( !ary[p] ) { 31 | primes[nprimes] = p 32 | nprimes = nprimes + 1 33 | } 34 | p = p + 1 35 | } 36 | 37 | // Copy/shrink the result array 38 | var rez = new [Int]{len=nprimes,value=0} 39 | var j = 0 40 | while( j < nprimes ) { 41 | rez[j] = primes[j] 42 | j = j + 1 43 | } 44 | return rez 45 | } 46 | func eq(a: [Int], b: [Int], n: Int)->Int 47 | { 48 | var result = 1 49 | var i = 0 50 | while (i < n) 51 | { 52 | if (a[i] != b[i]) 53 | { 54 | result = 0 55 | break 56 | } 57 | i = i + 1 58 | } 59 | return result 60 | } 61 | 62 | func main()->Int 63 | { 64 | var rez = sieve(20) 65 | var expected = new [Int]{2,3,5,7,11,13,17,19} 66 | return eq(rez,expected,8) 67 | } -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/OrNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeInteger; 5 | 6 | public class OrNode extends ArithNode { 7 | public OrNode(Node lhs, Node rhs) { super(lhs, rhs); } 8 | 9 | @Override public String label() { return "Or"; } 10 | @Override public String op() { return "|"; } 11 | @Override public String glabel() { return "|"; } 12 | 13 | 14 | @Override long doOp( long x, long y ) { return x | y; } 15 | @Override TypeInteger doOp(TypeInteger x, TypeInteger y) { 16 | return TypeInteger.BOT; 17 | } 18 | 19 | @Override 20 | public Node idealize() { 21 | Node lhs = in(1); 22 | Node rhs = in(2); 23 | Type t1 = lhs._type; 24 | Type t2 = rhs._type; 25 | 26 | // Or of 0. We do not check for (0|x) because this will already 27 | // canonicalize to (x|0) 28 | if( t2.isConstant() && t2 instanceof TypeInteger i && i.value()==0 ) 29 | return lhs; 30 | 31 | // Move constants to RHS: con*arg becomes arg*con 32 | if ( t1.isConstant() && !t2.isConstant() ) 33 | return swap12(); 34 | 35 | // Do we have ((x | (phi cons)) | con) ? 36 | // Do we have ((x | (phi cons)) | (phi cons)) ? 37 | // Push constant up through the phi: x | (phi con0|con0 con1|con1...) 38 | Node phicon = AddNode.phiCon(this,true); 39 | if( phicon!=null ) return phicon; 40 | 41 | return super.idealize(); 42 | } 43 | @Override Node copy(Node lhs, Node rhs) { return new OrNode(lhs,rhs); } 44 | } 45 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/CallEndMach.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | 6 | public class CallEndMach extends CallEndNode implements MachNode { 7 | public CallEndMach( CallEndNode n ) { super(n); } 8 | // MachNode specifics, shared across all CPUs 9 | public int _xslot; 10 | private RegMask _retMask; 11 | private RegMask _kills; 12 | public void cacheRegs(CodeGen code) { 13 | // Return mask depends on TFP (either GPR or FPR) 14 | _retMask = code._mach.retMask(call().tfp()); 15 | // Kill mask is all caller-saves, and any mirror stack slots for args 16 | // in registers. 17 | RegMaskRW kills = code._callerSave.copy(); 18 | // Start of stack slots 19 | int maxReg = code._mach.regs().length; 20 | // Incoming function arg slots, all low numbered in the RA 21 | int fslot = fun()._maxArgSlot; 22 | // Killed slots for this calls outgoing args 23 | int xslot = code._mach.maxArgSlot(call().tfp()); 24 | _xslot = (maxReg+fslot)+xslot; 25 | for( int i=0; i NONE = EnumSet.noneOf(Options.class); 31 | public static final EnumSet OPT = EnumSet.of(Options.OPTIMIZE,Options.SCCP,Options.CCP,Options.REGALLOC); 32 | public static final EnumSet OPT_B = EnumSet.of(Options.OPTIMIZE,Options.SCCP,Options.CCP,Options.REGALLOC,Options.SSA_DESTRUCTION_BOISSINOT_NOCOALESCE); 33 | public static final EnumSet OPT_ISSA = EnumSet.of(Options.OPTIMIZE,Options.ISSA,Options.SCCP,Options.CCP,Options.REGALLOC); 34 | public static final EnumSet OPT_ISSA_B = EnumSet.of(Options.OPTIMIZE,Options.ISSA,Options.SCCP,Options.CCP,Options.REGALLOC,Options.SSA_DESTRUCTION_BOISSINOT_NOCOALESCE); 35 | public static final EnumSet VERBOSE = EnumSet.range(DUMP_INITIAL_IR, DUMP_POST_CHAITIN_IR); 36 | public static final EnumSet OPT_VERBOSE = EnumSet.range(OPTIMIZE, DUMP_POST_CHAITIN_IR); 37 | } 38 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/Var.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.*; 4 | 5 | 6 | /** 7 | * The tracked fields are now complex enough to deserve a array-of-structs layout 8 | */ 9 | public class Var { 10 | 11 | public final String _name; // Declared name 12 | // These fields are not final for forward reference late updates or 13 | // promotions. 14 | public int _idx; // index in containing scope 15 | private Type _type; // Declared type 16 | public boolean _final; // Final field 17 | public boolean _fref; // Forward ref 18 | 19 | public Var(int idx, String name, Type type, boolean xfinal) { 20 | this(idx,name,type,xfinal,false); 21 | } 22 | public Var(int idx, String name, Type type, boolean xfinal, boolean fref) { 23 | _idx = idx; 24 | _name = name; 25 | _type = type; 26 | _final = xfinal; 27 | _fref = fref; 28 | } 29 | public Type type() { 30 | if( !_type.isFRef() ) return _type; 31 | // Update self to no longer use the forward ref type 32 | Type def = Compiler.TYPES.get(((TypeMemPtr)_type)._obj._name); 33 | return (_type=_type.meet(def)); 34 | } 35 | 36 | // Forward reference variables (not types) must be BOTTOM and 37 | // distinct from inferred variables 38 | public boolean isFRef() { return _fref; } 39 | 40 | public void defFRef(Type type, boolean xfinal) { 41 | assert isFRef() && xfinal; 42 | _type = type; 43 | _final = true; 44 | _fref = false; 45 | } 46 | 47 | @Override public String toString() { 48 | return _type.toString()+(_final ? " ": " !")+_name; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/MemAddX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class MemAddX86 extends MemOpX86 { 8 | MemAddX86( StoreNode st, Node base, Node idx, int off, int scale, int imm, Node val ) { 9 | super(st, st, base, idx, off, scale, imm, val ); 10 | } 11 | @Override public String op() { 12 | return (_imm == 1 ? "inc" : (_imm == -1 ? "dec" : "add")) + _sz; 13 | } 14 | // Register mask allowed as a result. 0 for no register. 15 | @Override public RegMask outregmap() { return null; } 16 | @Override public RegMask killmap() { return x86_64_v2.FLAGS_MASK; } 17 | @Override public void encoding( Encoding enc ) { 18 | // add something to memory 19 | // REX.W + 01 /r | REX.W + 81 /0 id 20 | // ADD [mem], imm32/reg 21 | short ptr = enc.reg(ptr()); 22 | short idx = enc.reg(idx()); 23 | short src = enc.reg(val()); 24 | 25 | enc.add1(x86_64_v2.rex(src, ptr, idx)); 26 | // opcode 27 | enc.add1( src == -1 ? (_imm==1 ? 0xFF : 0x81): 0x01); 28 | 29 | // includes modrm 30 | x86_64_v2.indirectAdr(_scale, idx, ptr, _off, src == -1 ? 0 : src, enc); 31 | if( src == -1 && _imm!=1 ) enc.add4(_imm); 32 | } 33 | // General form: "add [base + idx<<2 + 12] += src" 34 | @Override public void asm(CodeGen code, SB sb) { 35 | asm_address(code,sb); 36 | if( val()==null ) { 37 | if( _imm != 1 && _imm != -1 ) sb.p(" += #").p(_imm); 38 | } else sb.p(" += ").p(code.reg(val())); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/MulFNode.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node; 2 | 3 | import com.compilerprogramming.ezlang.compiler.type.Type; 4 | import com.compilerprogramming.ezlang.compiler.type.TypeFloat; 5 | 6 | import java.util.BitSet; 7 | 8 | public class MulFNode extends Node { 9 | public MulFNode(Node lhs, Node rhs) { super(null, lhs, rhs); } 10 | 11 | @Override public String label() { return "MulF"; } 12 | 13 | @Override public String glabel() { return "*"; } 14 | 15 | @Override 16 | public StringBuilder _print1(StringBuilder sb, BitSet visited) { 17 | in(1)._print0(sb.append("("), visited); 18 | in(2)._print0(sb.append("*"), visited); 19 | return sb.append(")"); 20 | } 21 | 22 | @Override 23 | public Type compute() { 24 | if (in(1)._type instanceof TypeFloat i0 && 25 | in(2)._type instanceof TypeFloat i1) { 26 | if (i0.isConstant() && i1.isConstant()) 27 | return TypeFloat.constant(i0.value()*i1.value()); 28 | } 29 | return in(1)._type.meet(in(2)._type); 30 | } 31 | 32 | @Override 33 | public Node idealize() { 34 | Node lhs = in(1); 35 | Node rhs = in(2); 36 | Type t1 = lhs._type; 37 | Type t2 = rhs._type; 38 | 39 | // Mul of 1. We do not check for (1*x) because this will already 40 | // canonicalize to (x*1) 41 | if ( t2.isConstant() && t2 instanceof TypeFloat i && i.value()==1 ) 42 | return lhs; 43 | 44 | // Move constants to RHS: con*arg becomes arg*con 45 | if ( t1.isConstant() && !t2.isConstant() ) 46 | return swap12(); 47 | 48 | return null; 49 | } 50 | @Override Node copy(Node lhs, Node rhs) { return new MulFNode(lhs,rhs); } 51 | } 52 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/SarIX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.CodeGen; 5 | import com.compilerprogramming.ezlang.compiler.codegen.Encoding; 6 | import com.compilerprogramming.ezlang.compiler.codegen.RegMask; 7 | import com.compilerprogramming.ezlang.compiler.node.MachNode; 8 | import com.compilerprogramming.ezlang.compiler.node.Node; 9 | 10 | import com.compilerprogramming.ezlang.compiler.node.*; 11 | 12 | // Arithmetic Right Shift 13 | public class SarIX86 extends MachConcreteNode implements MachNode { 14 | final int _imm; 15 | SarIX86( Node sari, int imm ) { super(sari); assert x86_64_v2.imm8(imm); _inputs.pop(); _imm = imm; } 16 | @Override public String op() { return "sari"; } 17 | @Override public String glabel() { return ">>"; } 18 | int opcode() { return 0xC1; } 19 | int mod() { return 7; } 20 | 21 | @Override public RegMask regmap(int i) { return x86_64_v2.RMASK; } 22 | @Override public RegMask outregmap() { return x86_64_v2.WMASK; } 23 | @Override public int twoAddress() { return 1; } 24 | 25 | @Override public void encoding(Encoding enc) { 26 | short dst = enc.reg(this); // Also src1 27 | enc.add1(x86_64_v2.rex(0, dst, 0)); 28 | enc.add1( opcode()); 29 | 30 | enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, mod(), dst) ); 31 | 32 | // immediate(4 bytes) 32 bits or (1 byte)8 bits 33 | if( x86_64_v2.imm8(_imm) ) enc.add1(_imm); 34 | else enc.add4(_imm); 35 | } 36 | 37 | @Override public void asm(CodeGen code, SB sb) { 38 | sb.p(code.reg(this)).p(" ").p(glabel()).p("= #").p(_imm); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/arm/LoadARM.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.arm; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.LoadNode; 6 | import com.compilerprogramming.ezlang.compiler.node.Node; 7 | import com.compilerprogramming.ezlang.compiler.type.TypeFloat; 8 | 9 | // Load memory addressing on ARM 10 | // Support imm, reg(direct), or reg+off(indirect) addressing 11 | // Base = base - base pointer, offset is added to base 12 | // idx = null 13 | // off = off - offset added to base 14 | 15 | public class LoadARM extends MemOpARM { 16 | LoadARM(LoadNode ld, Node base, Node idx, int off) { 17 | super(ld, base, idx, off, 0); 18 | } 19 | @Override public String op() { return "ld"+_sz; } 20 | @Override public RegMask outregmap() { return arm.MEM_MASK; } 21 | 22 | private static final int[] OP_LOADS = new int[]{ arm.OP_LOAD_IMM_8, arm.OP_LOAD_IMM_16, arm.OP_LOAD_IMM_32, arm.OP_LOAD_IMM_64, }; 23 | private int imm_op() { 24 | return _declaredType == TypeFloat.F32 ? arm.OPF_LOAD_IMM_32 25 | : _declaredType == TypeFloat.F64 ? arm.OPF_LOAD_IMM_64 26 | : OP_LOADS[_declaredType.log_size()]; 27 | } 28 | 29 | private static final int[] OP_LOAD_RS = new int[]{ arm.OP_LOAD_R_8 , arm.OP_LOAD_R_16 , arm.OP_LOAD_R_32 , arm.OP_LOAD_R_64, }; 30 | 31 | // ldr(immediate - unsigned offset) | ldr(register) 32 | @Override public void encoding( Encoding enc ) { 33 | ldst_encode(enc, imm_op(), OP_LOAD_RS[_declaredType.log_size()], this, size()); 34 | } 35 | @Override public void asm(CodeGen code, SB sb) { 36 | sb.p(code.reg(this)).p(","); 37 | asm_address(code,sb); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/util/Utils.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.util; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class Utils { 6 | public static RuntimeException TODO() { return TODO("Not yet implemented"); } 7 | public static RuntimeException TODO(String msg) { return new RuntimeException(msg); } 8 | 9 | /** 10 | * Fast, constant-time, element removal. Does not preserve order 11 | * 12 | * @param array ArrayList to modify 13 | * @param i element to be removed 14 | * @return element removed 15 | */ 16 | public static void del(ArrayList array, int i) { 17 | E last = array.removeLast(); 18 | if (i < array.size()) array.set(i, last); 19 | } 20 | 21 | /** 22 | * Search a list for an element by reference 23 | * 24 | * @param ary List to search in 25 | * @param x Object to be searched 26 | * @return >= 0 on success, -1 on failure 27 | */ 28 | public static int find( ArrayList ary, E x ) { 29 | for( int i=0; i= 0 on success, -1 on failure 40 | */ 41 | public static int find( E[] ary, E x ) { 42 | for( int i=0; i>>n); } 50 | 51 | // Fold a 64bit hash into 32 bits 52 | public static int fold( long x ) { return (int)((x>>32) ^ x); } 53 | } 54 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/TMPX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | import com.compilerprogramming.ezlang.compiler.type.TypeMemPtr; 7 | 8 | public class TMPX86 extends ConstantNode implements MachNode, RIPRelSize{ 9 | TMPX86(ConstantNode con ) { super(con); } 10 | @Override public String op() { return "ldp"; } 11 | @Override public RegMask regmap(int i) { return null; } 12 | @Override public RegMask outregmap() { return x86_64_v2.WMASK; } 13 | @Override public boolean isClone() { return true; } 14 | @Override public Node copy() { return new TMPX86(this); } 15 | 16 | @Override public void encoding( Encoding enc ) { 17 | short dst = enc.reg(this); 18 | x86_64_v2.rexF(dst, 0, 0, true, enc); 19 | enc.add1(0x8D).add1(x86_64_v2.modrm(x86_64_v2.MOD.INDIRECT, dst, 0b101)).add4(0); 20 | int opLen = 1/*rexF*/+1/*opcode 0x8D*/+1/*modrm*/+4/*pc rel offset*/; 21 | // Base of constant array 22 | TypeMemPtr tmp = (TypeMemPtr)_con; 23 | int baseOff = tmp._obj.aryBase(); 24 | enc.largeConstant(this,tmp._obj,opLen-baseOff,2/*ELF encoding PC32*/); 25 | } 26 | 27 | // Delta is from opcode start 28 | @Override public byte encSize(int delta) { return (byte)7; } 29 | 30 | // Delta is from opcode start 31 | @Override public void patch( Encoding enc, int opStart, int opLen, int delta ) { 32 | enc.patch4(opStart+opLen-4,delta-opLen); 33 | } 34 | 35 | @Override public void asm(CodeGen code, SB sb) { 36 | _con.print(sb.p(code.reg(this)).p(" = #")); 37 | } 38 | @Override public boolean eq(Node n) { return this==n; } 39 | } 40 | -------------------------------------------------------------------------------- /seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/node/cpus/x86_64_v2/NotX86.java: -------------------------------------------------------------------------------- 1 | package com.compilerprogramming.ezlang.compiler.node.cpus.x86_64_v2; 2 | 3 | import com.compilerprogramming.ezlang.compiler.util.SB; 4 | import com.compilerprogramming.ezlang.compiler.codegen.*; 5 | import com.compilerprogramming.ezlang.compiler.node.*; 6 | 7 | public class NotX86 extends MachConcreteNode implements MachNode { 8 | NotX86(NotNode not) { super(not); } 9 | @Override public String op() { return "not"; } 10 | @Override public RegMask regmap(int i) { return x86_64_v2.RMASK; } 11 | @Override public RegMask outregmap() { return x86_64_v2.RMASK; } 12 | @Override public RegMask killmap() { return x86_64_v2.FLAGS_MASK; } 13 | 14 | @Override public void encoding( Encoding enc ) { 15 | assert !(in(1) instanceof NotNode); // Cleared out by peeps 16 | assert !(in(1) instanceof BoolNode); // Cleared out by peeps 17 | short dst = enc.reg(this ); 18 | short src = enc.reg(in(1)); 19 | 20 | // Pre-zero using XOR dst,dst; since zero'd will not have a 21 | // byte-dependency from the setz. Can skip REX is dst is low 8, makes 22 | // this a 32b xor, which will also zero the high bits. 23 | if( dst >= 8 ) enc.add1(x86_64_v2.rex(dst, dst, 0)); 24 | enc.add1(0x33); // opcode 25 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, dst)); 26 | 27 | // test rdi,rdi 28 | enc.add1(x86_64_v2.rex(src, src, 0)); 29 | enc.add1(0x85); 30 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, src, src)); 31 | 32 | // setz (sete dil) 33 | enc.add1(x86_64_v2.rex(dst, 0, 0)); 34 | enc.add1(0x0F); 35 | enc.add1(0x94); 36 | enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, 0)); 37 | } 38 | @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)); } 39 | } 40 | --------------------------------------------------------------------------------