diff options
| author | azidar | 2015-03-03 13:31:28 -0800 |
|---|---|---|
| committer | azidar | 2015-03-03 13:31:28 -0800 |
| commit | 785dedccccbcf482970f1c7455008810d6318164 (patch) | |
| tree | 17b3451b21f26218d68d0477c4716eb5c88f51b1 | |
| parent | 5e333ec85ebbae58686d225b7e03fcff9376d979 (diff) | |
In-progress, working on inferring types pass
| -rw-r--r-- | notes/primop-inference.txt | 73 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 82 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 302 | ||||
| -rw-r--r-- | test/passes/infer-types/primops.fir | 114 |
4 files changed, 415 insertions, 156 deletions
diff --git a/notes/primop-inference.txt b/notes/primop-inference.txt new file mode 100644 index 00000000..ec704ba6 --- /dev/null +++ b/notes/primop-inference.txt @@ -0,0 +1,73 @@ +The design of the primitive operations follows the following principles: +(1) if operand types are known (i.e. FIRRTL front-end), primops whose return type is statically known (no future type introspection needed) are available +(2) if operand types are not known (i.e. hand-writing FIRRTL pass), generic primops can be used, and a future pass will perform type introspection to replace the generic with the specific primop +(3) the FIRRTL's lowered form will never contain any generic primops +(4) resultant widths are always large enough to represent any possible output +(5) specific primops do not grow widths (e.g. add-wrap, sub-wrap) and should be used if that behavior is desired +(6) except for mux, mux-u, and mux-s, all primops can accept operands of differing width to enable optimizations in the backend +(7) autopadding on connect is not allowed, and one should use the pad!/-u/-s expression to autopad + +TODO: +rederive div,mod,quo,rem widths. +Write explanations in terms of formulas. +Reread all explanations. +Finish adding primops. + +add + adduu(a,b) -> u, max(a.w,b.w) + 1 + addus(a,b) -> s, max(a.w,b.w) + 1 + addsu(a,b) -> s, max(a.w,b.w) + 1 + addss(a,b) -> s, max(a.w,b.w) + 1 + +sub + subuu(a,b) -> s, max(a.w,b.w) + 1 ; 0@<UInt,3> - 7@<UInt,3> = -7@<SInt,4> + subus(a,b) -> s, max(a.w,b.w) + 1 ; 7@<UInt,3> - -8@<SInt,4> = 15@<SInt,5> + subsu(a,b) -> s, max(a.w,b.w) + 1 ; -8@<SInt,4> - 7@<UInt,3> = -15@<SInt,5> + subss(a,b) -> s, max(a.w,b.w) + 1 ; -8@<UInt,4> - 7@<SInt,4> = -15@<SInt,5> + +mul + muluu(a,b) -> u,a.w+b.w + mulus(a,b) -> s,a.w+b.w + mulsu(a,b) -> s,a.w+b.w + mulss(a,b) -> s,a.w+b.w + +div + divuu(a,b) -> u,a.w ; if divide by 1 + divus(a,b) -> s,a.w+1 ; if divide by -1 + divsu(a,b) -> s,a.w ; if divide by 1 + divss(a,b) -> s,a.w+1 ; if divide by -1 + +mod + moduu(a,d) -> u,d.w + modus(a,d) -> u,d.w-1 + modsu(a,d) -> u,d.w + modss(a,d) -> u,d.w-1 + +rem + remuu(a,b) -> u,min(a.w,b.w) ; 15 % 16 = 15. All remainders must be less than b or a. + remus(a,b) -> u,b.w ; -1 % 32 = 31. Remainder can be larger than abs(a), but not larger than b. + remsu(a,b) -> s,b.w ; 1 % -32 = -31. abs(rem) can be larger than abs(a), but not larger than abs(b). + remss(a,b) -> s,b.w ; strictly superset of us and su. + +add-mod + add-moduu(a,b) -> u, a.w + add-modus(a,b) -> u, a.w + add-modsu(a,b) -> s, a.w + add-modss(a,b) -> s, a.w + +sub-mod + sub-moduu(a,b) -> u, a.w + sub-modus(a,b) -> u, a.w + sub-modsu(a,b) -> s, a.w + sub-modss(a,b) -> s, a.w + + +Proof: +add-moduu -> u +take inverse: +sub-moduu -> u +add-modus -> u +add-modsu -> s with width of first operand + +add-mod and sub-mod always return the type and width of the first operand. + diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index 259bba10..206401d8 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -14,27 +14,89 @@ public defstruct IntWidth <: Width : public defstruct PrimOp public val ADD-OP = PrimOp() -public val ADD-MOD-OP = PrimOp() +public val ADD-UU-OP = PrimOp() +public val ADD-US-OP = PrimOp() +public val ADD-SU-OP = PrimOp() +public val ADD-SS-OP = PrimOp() public val SUB-OP = PrimOp() -public val SUB-MOD-OP = PrimOp() +public val SUB-UU-OP = PrimOp() +public val SUB-US-OP = PrimOp() +public val SUB-SU-OP = PrimOp() +public val SUB-SS-OP = PrimOp() public val TIMES-OP = PrimOp() +public val TIMES-UU-OP = PrimOp() +public val TIMES-US-OP = PrimOp() +public val TIMES-SU-OP = PrimOp() +public val TIMES-SS-OP = PrimOp() public val DIVIDE-OP = PrimOp() +public val DIVIDE-UU-OP = PrimOp() +public val DIVIDE-US-OP = PrimOp() +public val DIVIDE-SU-OP = PrimOp() +public val DIVIDE-SS-OP = PrimOp() public val MOD-OP = PrimOp() -public val SHIFT-LEFT-OP = PrimOp() -public val SHIFT-RIGHT-OP = PrimOp() +public val MOD-UU-OP = PrimOp() +public val MOD-US-OP = PrimOp() +public val MOD-SU-OP = PrimOp() +public val MOD-SS-OP = PrimOp() +public val ADD-WRAP-OP = PrimOp() +public val ADD-WRAP-UU-OP = PrimOp() +public val ADD-WRAP-US-OP = PrimOp() +public val ADD-WRAP-SU-OP = PrimOp() +public val ADD-WRAP-SS-OP = PrimOp() +public val SUB-WRAP-OP = PrimOp() +public val SUB-WRAP-UU-OP = PrimOp() +public val SUB-WRAP-US-OP = PrimOp() +public val SUB-WRAP-SU-OP = PrimOp() +public val SUB-WRAP-SS-OP = PrimOp() +public val LESS-OP = PrimOp() +public val LESS-UU-OP = PrimOp() +public val LESS-US-OP = PrimOp() +public val LESS-SU-OP = PrimOp() +public val LESS-SS-OP = PrimOp() +public val LESS-EQ-OP = PrimOp() +public val LESS-EQ-UU-OP = PrimOp() +public val LESS-EQ-US-OP = PrimOp() +public val LESS-EQ-SU-OP = PrimOp() +public val LESS-EQ-SS-OP = PrimOp() +public val GREATER-OP = PrimOp() +public val GREATER-UU-OP = PrimOp() +public val GREATER-US-OP = PrimOp() +public val GREATER-SU-OP = PrimOp() +public val GREATER-SS-OP = PrimOp() +public val GREATER-EQ-OP = PrimOp() +public val GREATER-EQ-UU-OP = PrimOp() +public val GREATER-EQ-US-OP = PrimOp() +public val GREATER-EQ-SU-OP = PrimOp() +public val GREATER-EQ-SS-OP = PrimOp() +public val EQUAL-OP = PrimOp() +public val EQUAL-UU-OP = PrimOp() +public val EQUAL-SS-OP = PrimOp() +public val MULTIPLEX-OP = PrimOp() +public val MULTIPLEX-UU-OP = PrimOp() +public val MULTIPLEX-SS-OP = PrimOp() public val PAD-OP = PrimOp() +public val PAD-U-OP = PrimOp() +public val PAD-S-OP = PrimOp() +public val AS-UINT-OP = PrimOp() +public val AS-UINT-U-OP = PrimOp() +public val AS-UINT-S-OP = PrimOp() +public val AS-SINT-OP = PrimOp() +public val AS-SINT-U-OP = PrimOp() +public val AS-SINT-S-OP = PrimOp() +public val SHIFT-LEFT-OP = PrimOp() +public val SHIFT-LEFT-U-OP = PrimOp() +public val SHIFT-LEFT-S-OP = PrimOp() +public val SHIFT-RIGHT-U-OP = PrimOp() +public val SHIFT-RIGHT-S-OP = PrimOp() +public val CONVERT-OP = PrimOp() +public val CONVERT-U-OP = PrimOp() +public val CONVERT-S-OP = PrimOp() public val BIT-AND-OP = PrimOp() public val BIT-OR-OP = PrimOp() public val BIT-XOR-OP = PrimOp() public val CONCAT-OP = PrimOp() public val BIT-SELECT-OP = PrimOp() public val BITS-SELECT-OP = PrimOp() -public val MULTIPLEX-OP = PrimOp() -public val LESS-OP = PrimOp() -public val LESS-EQ-OP = PrimOp() -public val GREATER-OP = PrimOp() -public val GREATER-EQ-OP = PrimOp() -public val EQUAL-OP = PrimOp() public definterface Expression public defmulti type (e:Expression) -> Type diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 25ce27bd..6a518e49 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -342,155 +342,173 @@ defn initialize-registers (c:Circuit) : ; Type errors are not checked in this pass, as this is ; postponed for a later/earlier pass. -defmethod type (v:UIntValue) : - UIntType(width(v)) - -defmethod type (v:SIntValue) : - SIntType(width(v)) - -defn put-type (e:Expression, t:Type) -> Expression : +defn get-primop-rettype (e:DoPrim) -> Type : + defn u() = UIntType(UnknownWidth()) + defn s() = SIntType(UnknownWidth()) match(e) : - (e:WRef) : WRef(name(e), t, kind(e), dir(e)) - (e:WField) : WField(exp(e), name(e), t, dir(e)) - (e:WIndex) : WIndex(exp(e), value(e), t, dir(e)) - (e:DoPrim) : DoPrim(op(e), args(e), consts(e), t) - (e:ReadPort) : ReadPort(mem(e), index(e), t) - (e) : e - -defn lookup-port (ports: Streamable<Port>, port-name: Symbol) : - for port in ports find : - name(port) == port-name - -defn infer (op:PrimOp, arg-types: List<Type>) -> Type : - defn wipe-width (t:Type) : - match(t) : - (t:UIntType) : UIntType(UnknownWidth()) - (t:SIntType) : SIntType(UnknownWidth()) - - defn arg0 () : wipe-width(arg-types[0]) - defn arg1 () : wipe-width(arg-types[1]) - ; TODO subtle, not entirely figured out - switch {op == _} : - ADD-OP : arg0() - ADD-MOD-OP : arg0() - SUB-OP : arg0() - SUB-MOD-OP : arg0() - TIMES-OP : arg0() - DIVIDE-OP : arg0() - MOD-OP : arg0() - SHIFT-LEFT-OP : arg0() - SHIFT-RIGHT-OP : arg0() - PAD-OP : arg0() - BIT-AND-OP : arg0() - BIT-OR-OP : arg0() - BIT-XOR-OP : arg0() - CONCAT-OP : arg0() - BIT-SELECT-OP : UIntType(UnknownWidth()) - BITS-SELECT-OP : arg0() - MULTIPLEX-OP : arg0() - LESS-OP : UIntType(UnknownWidth()) - LESS-EQ-OP : UIntType(UnknownWidth()) - GREATER-OP : UIntType(UnknownWidth()) - GREATER-EQ-OP : UIntType(UnknownWidth()) - EQUAL-OP : UIntType(UnknownWidth()) - -defn bundle-field-type (t:Type, n:Symbol) -> Type : - match(t) : - (t:BundleType) : - match(lookup-port(ports(t), n)) : - (p:Port) : type(p) - (p) : UnknownType() - (t) : UnknownType() - -defn vector-elem-type (t:Type) -> Type : - match(t) : - (t:VectorType) : type(t) - (t) : UnknownType() - -;e is the environment that contains all definitions seen so far. -defn infer (c:Stmt, e:List<KeyValue<Symbol, Type>>) -> [Stmt, List<KeyValue<Symbol,Type>>] : - defn infer-exp (e:Expression, env:List<KeyValue<Symbol,Type>>) : - match(map(infer-exp{_, env}, e)) : - (e:WRef) : - put-type(e, lookup!(env, name(e))) - (e:WField) : - put-type(e, bundle-field-type(type(exp(e)), name(e))) - (e:WIndex) : - put-type(e, vector-elem-type(type(exp(e)))) - (e:UIntValue) : e - (e:SIntValue) : e - (e:DoPrim) : - put-type(e, infer(op(e), map(type, args(e)))) - (e:ReadPort) : - put-type(e, vector-elem-type(type(mem(e)))) - (e:Null) : e - - defn element-type (e:Element, env:List<KeyValue<Symbol,Type>>) : - match(e) : - (e:Instance) : - val t = type(infer-exp(module(e), env)) - match(t) : - (t:BundleType) : - BundleType $ to-list $ - for p in ports(t) filter : - direction(p) == OUTPUT - (t) : UnknownType() - (e) : type(e) - - match(c) : - (c:LetRec) : - val e* = append(elem-types, e) where : - val elem-types = - for entry in entries(c) map : - key(entry) => element-type(value(entry), e) - val c* = map(infer-exp{_, e*}, c) - val [body*, be] = infer(body(c*), e*) - [LetRec(entries(c*), body*), e] - (c) : - match(map(infer-exp{_, e}, c)) : - (c:DefWire) : - [c, List(entry, e)] where : - val entry = name(c) => type(c) - (c:DefRegister) : - [c, List(entry, e)] where : - val entry = name(c) => type(c) - (c:DefInstance) : - [c, List(entry, e)] where : - val entry = name(c) => type(module(c)) - (c:DefMemory) : - [c, List(entry, e)] where : - val entry = name(c) => type(c) - (c:WDefAccessor) : - [c, List(entry, e)] where : - val src-type = type(source(c)) - val entry = name(c) => vector-elem-type(src-type) - (c:Begin) : - var current-e: List<KeyValue<Symbol,Type>> = e - val body* = for c in body(c) map : - val [c*, e*] = infer(c, current-e) - current-e = e* - c* - [Begin(body*), current-e] - (c) : - defn infer-comm (c:Stmt) : - val [c* e*] = infer(c, e) - c* - val c* = map(infer-comm, c) - [c*, e] - -defn infer (m:Module, e:List<KeyValue<Symbol, Type>>) -> Module : - val env = append{_, e} $ + (e:ADD-OP ) : u() + (e:ADD-UU-OP ) : u() + (e:ADD-US-OP ) : s() + (e:ADD-SU-OP ) : s() + (e:ADD-SS-OP ) : s() + (e:SUB-OP ) : s() + (e:SUB-UU-OP ) : s() + (e:SUB-US-OP ) : s() + (e:SUB-SU-OP ) : s() + (e:SUB-SS-OP ) : s() + (e:TIMES-OP ) : u() + (e:TIMES-UU-OP ) : u() + (e:TIMES-US-OP ) : s() + (e:TIMES-SU-OP ) : s() + (e:TIMES-SS-OP ) : s() + (e:DIVIDE-OP ) : u() + (e:DIVIDE-UU-OP ) : u() + (e:DIVIDE-US-OP ) : s() + (e:DIVIDE-SU-OP ) : s() + (e:DIVIDE-SS-OP ) : s() + (e:MOD-OP ) : u() + (e:MOD-UU-OP ) : s() + (e:MOD-US-OP ) : s() + (e:MOD-SU-OP ) : s() + (e:MOD-SS-OP ) : s() + (e:QUOTIENT-OP ) : u() + (e:QUOTIENT-UU-OP ) : u() + (e:QUOTIENT-US-OP ) : s() + (e:QUOTIENT-SU-OP ) : s() + (e:QUOTIENT-SS-OP ) : s() + (e:REMAINDER-OP ) : u() + (e:REMAINDER-UU-OP ) : u() + (e:REMAINDER-US-OP ) : s() + (e:REMAINDER-SU-OP ) : u() + (e:REMAINDER-SS-OP ) : s() + (e:ADD-WRAP-OP ) : u() + (e:ADD-WRAP-UU-OP ) : u() + (e:ADD-WRAP-US-OP ) : s() + (e:ADD-WRAP-SU-OP ) : s() + (e:ADD-WRAP-SS-OP ) : s() + (e:SUB-WRAP-OP ) : u() + (e:SUB-WRAP-UU-OP ) : u() + (e:SUB-WRAP-US-OP ) : s() + (e:SUB-WRAP-SU-OP ) : s() + (e:SUB-WRAP-SS-OP ) : s() + (e:LESS-OP ) : u() + (e:LESS-UU-OP ) : u() + (e:LESS-US-OP ) : u() + (e:LESS-SU-OP ) : u() + (e:LESS-SS-OP ) : u() + (e:LESS-EQ-OP ) : u() + (e:LESS-EQ-UU-OP ) : u() + (e:LESS-EQ-US-OP ) : u() + (e:LESS-EQ-SU-OP ) : u() + (e:LESS-EQ-SS-OP ) : u() + (e:GREATER-OP ) : u() + (e:GREATER-UU-OP ) : u() + (e:GREATER-US-OP ) : u() + (e:GREATER-SU-OP ) : u() + (e:GREATER-SS-OP ) : u() + (e:GREATER-EQ-OP ) : u() + (e:GREATER-EQ-UU-OP ) : u() + (e:GREATER-EQ-US-OP ) : u() + (e:GREATER-EQ-SU-OP ) : u() + (e:GREATER-EQ-SS-OP ) : u() + (e:EQUAL-OP ) : u() + (e:EQUAL-UU-OP ) : u() + (e:EQUAL-SS-OP ) : u() + (e:MULTIPLEX-OP ) : u() + (e:MULTIPLEX-UU-OP ) : u() + (e:MULTIPLEX-SS-OP ) : s() + (e:PAD-OP ) : u() + (e:PAD-U-OP ) : u() + (e:PAD-S-OP ) : s() + (e:AS-UINT-OP ) : u() + (e:AS-UINT-U-OP ) : u() + (e:AS-UINT-S-OP ) : u() + (e:AS-SINT-OP ) : s() + (e:AS-SINT-U-OP ) : s() + (e:AS-SINT-S-OP ) : s() + (e:SHIFT-LEFT-OP ) : u() + (e:SHIFT-LEFT-U-OP ) : u() + (e:SHIFT-LEFT-S-OP ) : s() + (e:SHIFT-RIGHT-OP ) : u() + (e:SHIFT-RIGHT-U-OP ) : u() + (e:SHIFT-RIGHT-S-OP ) : u() + (e:CONVERT-OP ) : u() + (e:CONVERT-U-OP ) : u() + (e:CONVERT-S-OP ) : u() + (e:BIT-AND-OP ) : u() + (e:BIT-OR-OP ) : u() + (e:BIT-XOR-OP ) : u() + (e:CONCAT-OP ) : u() + (e:BIT-SELECT-OP ) : u() + (e:BITS-SELECT-OP ) : u() + +defn type (m:Module) -> Type : + BundleType(ports(module(s))) + +defn get-type (b:Symbol,l:List<KeyValue<Symbol,Type>>) -> Type : + val contains? = for kv in l any? : b == key(kv) + if contains? : + label<Type> myret : + for kv in l do : + if b == key(kv) : myret(value(kv)) + else : UnknownType() + +defn get-bundle-subtype (v:Type,s:Symbol) -> Type : + match(v) : + (v:BundleType) : + val contains? = for p in ports(v) any? : name(p) == s + if contains? : + label<Type> myret : + for p in ports(v) do : + if b == name(p) : myret(type(p)) + else : UnknownType() + (v) : UnknownType() + +defn get-vector-subtype (v:Type) -> Type : + match(v) : + (v:VectorType) : type(v) + (v) : UnknownType() + +defn infer-types (e:Expression, l:List<KeyValue<Symbol,Type>>) -> Expression : + match(map(infer-types{_,l},e)) : + (e:WRef) : WRef(name(e), get-type(name(e),l)) + (e:WField) : WField(exp(e),name(e), get-bundle-subtype(type(exp(e)))) + (e:WIndex) : WIndex(exp(e),name(e), get-vector-subtype(type(exp(e)))) + (e:DoPrim) : DoPrim(op(e),args(e),consts(e),get-primop-rettype(e)) + (e:ReadPort) : ReadPort(mem(e),index(e),get-vector-subtype(type(mem(e)))) + (e:UIntValue|SIntValue|Null) : e + +defn infer-types (s:Stmt, l:List<KeyValue<Symbol,Type>>) -> [Stmt, List<KeyValue<Symbol,Type>>] + match(map(infer-types{_,l},s)) : + (s:LetRec) : [s,l] ;TODO, this is wrong but we might be getting rid of letrecs? + (s:Begin) : + var env = l + val body* = + for s in body(s) map : + val [s*,l*] = infer-types(s,env) + env = l* + s* + [Begin(body*),env] + (s:DefWire|DefRegister|DefMemory) : [s,List(name(s) => type(s),l)] + (s:DefInstance) : [s, List(name(s) => type(module(s)),l)] + (s:DefNode) : [s, List(name(s) => type(value(s)),l)] + (s:WDefAccessor) : [s, List(name(s) => type(source(s)),l)] + (s:Conditionally|Connect|EmptyStmt) : [s,l] + +defn infer-types (m:Module, l:List<KeyValue<Symbol,Type>>) -> Module : + val ptypes = for p in ports(m) map : name(p) => type(p) - val [body*, e*] = infer(body(m), env) - Module(name(m), ports(m), body*) + infer-types(body(m),append(ptypes, l)) defn infer-types (c:Circuit) -> Circuit : - val env = + val l = for m in modules(c) map : name(m) => BundleType(ports(m)) - Circuit(map(infer{_, env}, modules(c)), - main(c)) + Circuit{ _, main(c) } $ + for m in modules(c) map : + infer-types(m,l) + ;============= INFER DIRECTIONS ============================ defn flip (d:Direction) : diff --git a/test/passes/infer-types/primops.fir b/test/passes/infer-types/primops.fir index 244853cf..2a29efbf 100644 --- a/test/passes/infer-types/primops.fir +++ b/test/passes/infer-types/primops.fir @@ -3,8 +3,114 @@ ;CHECK: Infer Types circuit top : module top : - wire io : {input x : UInt, output y : UInt} - node a = io.x -;CHECK: wire io : {input x : UInt@<t:UInt>, output y : UInt@<t:UInt>}@<t:{input x : UInt@<t:UInt>, output y : UInt@<t:UInt>}> -;CHECK: node a = io@<t:{input x : UInt@<t:UInt>, output y : UInt@<t:UInt>}>.x@<t:UInt> + wire a : UInt(16) + wire b : UInt(8) + wire c : SInt(16) + wire d : SInt(8) + + ;add + module add : + node w = adduu(a,b) ;CHECK: node w = adduu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = addus(a,d) ;CHECK: node x = addus(a@<t:UInt>,d@<t:SInt>)@<t:SInt> + node y = addsu(c,b) ;CHECK: node y = addsu(c@<t:SInt>,b@<t:UInt>)@<t:SInt> + node z = addss(c,d) ;CHECK: node z = addss(c@<t:SInt>,d@<t:SInt>)@<t:SInt> + ;sub + module sub : + node w = subuu(a,b) ;CHECK: node w = subuu(a@<t:UInt>,b@<t:UInt>)@<t:SInt> + node x = subus(a,d) ;CHECK: node x = subus(a@<t:UInt>,d@<t:SInt>)@<t:SInt> + node y = subsu(c,b) ;CHECK: node y = subsu(c@<t:SInt>,b@<t:UInt>)@<t:SInt> + node z = subss(c,d) ;CHECK: node z = subss(c@<t:SInt>,d@<t:SInt>)@<t:SInt> + ;mul + module mul : + node w = muluu(a,b) ;CHECK: node w = muluu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = mulus(a,d) ;CHECK: node x = mulus(a@<t:UInt>,d@<t:SInt>)@<t:SInt> + node y = mulsu(c,b) ;CHECK: node y = mulsu(c@<t:SInt>,b@<t:UInt>)@<t:SInt> + node z = mulss(c,d) ;CHECK: node z = mulss(c@<t:SInt>,d@<t:SInt>)@<t:SInt> + ;div + module div : + node w = divuu(a,b) ;CHECK: node w = divuu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = divus(a,d) ;CHECK: node x = divus(a@<t:UInt>,d@<t:SInt>)@<t:SInt> + node y = divsu(c,b) ;CHECK: node y = divsu(c@<t:SInt>,b@<t:UInt>)@<t:SInt> + node z = divss(c,d) ;CHECK: node z = divss(c@<t:SInt>,d@<t:SInt>)@<t:SInt> + ;mod + module mod : + node w = moduu(a,b) ;CHECK: node w = moduu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = modus(a,d) ;CHECK: node x = modus(a@<t:UInt>,d@<t:SInt>)@<t:SInt> + node y = modsu(c,b) ;CHECK: node y = modsu(c@<t:SInt>,b@<t:UInt>)@<t:SInt> + node z = modss(c,d) ;CHECK: node z = modss(c@<t:SInt>,d@<t:SInt>)@<t:SInt> + ;rem + module rem : + node w = remuu(a,b) ;CHECK: node w = remuu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = remus(a,d) ;CHECK: node x = remus(a@<t:UInt>,d@<t:SInt>)@<t:SInt> + node y = remsu(c,b) ;CHECK: node y = remsu(c@<t:SInt>,b@<t:UInt>)@<t:SInt> + node z = remss(c,d) ;CHECK: node z = remss(c@<t:SInt>,d@<t:SInt>)@<t:SInt> + ;add-mod + module add-mod : + node w = add-moduu(a,b) ;CHECK: node w = add-moduu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = add-modus(a,d) ;CHECK: node x = add-modus(a@<t:UInt>,d@<t:SInt>)@<t:UInt> + node y = add-modsu(c,b) ;CHECK: node y = add-modsu(c@<t:SInt>,b@<t:UInt>)@<t:SInt> + node z = add-modss(c,d) ;CHECK: node z = add-modss(c@<t:SInt>,d@<t:SInt>)@<t:SInt> + ;sub-mod + module sub-mod : + node w = sub-moduu(a,b) ;CHECK: node w = sub-moduu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = sub-modus(a,d) ;CHECK: node x = sub-modus(a@<t:UInt>,d@<t:SInt>)@<t:UInt> + node y = sub-modsu(c,b) ;CHECK: node y = sub-modsu(c@<t:SInt>,b@<t:UInt>)@<t:SInt> + node z = sub-modss(c,d) ;CHECK: node z = sub-modss(c@<t:SInt>,d@<t:SInt>)@<t:SInt> + ;lt + module lt : + node w = ltuu(a,b) ;CHECK: node w = ltuu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = ltus(a,d) ;CHECK: node x = ltus(a@<t:UInt>,d@<t:SInt>)@<t:UInt> + node y = ltsu(c,b) ;CHECK: node y = ltsu(c@<t:SInt>,b@<t:UInt>)@<t:UInt> + node z = ltss(c,d) ;CHECK: node z = ltss(c@<t:SInt>,d@<t:SInt>)@<t:UInt> + ;leq + module leq : + node w = lequu(a,b) ;CHECK: node w = lequu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = lequs(a,d) ;CHECK: node x = lequs(a@<t:UInt>,d@<t:SInt>)@<t:UInt> + node y = leqsu(c,b) ;CHECK: node y = leqsu(c@<t:SInt>,b@<t:UInt>)@<t:UInt> + node z = leqss(c,d) ;CHECK: node z = leqss(c@<t:SInt>,d@<t:SInt>)@<t:UInt> + ;gt + module gt : + node w = gtuu(a,b) ;CHECK: node w = gtuu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = gtus(a,d) ;CHECK: node x = gtus(a@<t:UInt>,d@<t:SInt>)@<t:UInt> + node y = gtsu(c,b) ;CHECK: node y = gtsu(c@<t:SInt>,b@<t:UInt>)@<t:UInt> + node z = gtss(c,d) ;CHECK: node z = gtss(c@<t:SInt>,d@<t:SInt>)@<t:UInt> + ;geq + module geq : + node w = gequu(a,b) ;CHECK: node w = gequu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = gequs(a,d) ;CHECK: node x = gequs(a@<t:UInt>,d@<t:SInt>)@<t:UInt> + node y = geqsu(c,b) ;CHECK: node y = geqsu(c@<t:SInt>,b@<t:UInt>)@<t:UInt> + node z = geqss(c,d) ;CHECK: node z = geqss(c@<t:SInt>,d@<t:SInt>)@<t:UInt> + ;pad + module pad : + node w = paduu(a,b) ;CHECK: node w = paduu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = padus(a,d) ;CHECK: node x = padus(a@<t:UInt>,d@<t:SInt>)@<t:UInt> + node y = padsu(c,b) ;CHECK: node y = padsu(c@<t:SInt>,b@<t:UInt>)@<t:SInt> + node z = padss(c,d) ;CHECK: node z = padss(c@<t:SInt>,d@<t:SInt>)@<t:SInt> + ;and + module and : + node w = and(a,b) ;CHECK: node w = and(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + module or : + node w = or(a,b) ;CHECK: node w = or(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + module xor : + node w = xor(a,b) ;CHECK: node w = xor(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + ;concat + node w = concat(a,b) ;CHECK: node w = concat(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + ;equal + node w = equaluu(a,b) ;CHECK: node w = equaluu(a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = equalus(a,d) ;CHECK: node x = equalus(a@<t:UInt>,d@<t:SInt>)@<t:UInt> + node y = equalsu(c,b) ;CHECK: node y = equalsu(c@<t:SInt>,b@<t:UInt>)@<t:UInt> + node z = equalss(c,d) ;CHECK: node z = equalss(c@<t:SInt>,d@<t:SInt>)@<t:UInt> + ;mux + node w = muxuu(e,a,b) ;CHECK: node w = muxuu(e@<t:UInt>,a@<t:UInt>,b@<t:UInt>)@<t:UInt> + node x = muxus(e,a,d) ;CHECK: node x = muxus(e@<t:UInt>,a@<t:UInt>,d@<t:SInt>)@<t:SInt> + node y = muxsu(e,c,b) ;CHECK: node y = muxsu(e@<t:UInt>,c@<t:SInt>,b@<t:UInt>)@<t:SInt> + node z = muxss(e,c,d) ;CHECK: node z = muxss(e@<t:UInt>,c@<t:SInt>,d@<t:SInt>)@<t:SInt> + ;shl + ;shr + ;bit + ;bits + + + + ;CHECK: Finished Infer Types |
