inst "hlt" do @control.halt end inst "mov $ #" do uop { @decode.outaddr_a; @decode.outdata_b; @rf.store } end inst "mov $ $" do uop { @decode.outaddr_b; @rf.outdata; @tmp0.loaddata } uop { @decode.outaddr_a; @tmp0.outdata; @rf.store } end inst "mov [#] #" do uop { @decode.outaddr_a; @decode.outdata_b; @memory.store } end inst "mov [#] $" do uop { @decode.outaddr_b; @rf.outdata; @tmp0.loaddata } uop { @decode.outaddr_a; @tmp0.outdata; @memory.store } end inst "mov [$] #" do uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @decode.outdata_b; @tmp0.outaddr; @memory.store } end inst "mov [$] $" do uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @decode.outaddr_b; @rf.outdata; @tmp1.loaddata } uop { @tmp0.outaddr; @tmp1.outdata; @memory.store } end inst "mov $ [#]" do uop { @decode.outaddr_b; @memory.outdata; @tmp0.loaddata } uop { @decode.outaddr_a; @tmp0.outdata; @rf.store } end inst "mov $ [$]" do uop { @decode.outaddr_b; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outaddr; @memory.outdata; @tmp1.loaddata } uop { @decode.outaddr_a; @tmp1.outdata; @rf.store } end inst "skipz $" do uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outdata; @control.set_uip_if_nonzero; constaddr($eom) } uop { @decode.clear } decode_loop = uip() uop { @pc.increment; @pc.outaddr; @memory.outdata; @decode.decode } uop { @decode.outdata_needmore; @control.set_uip_if_nonzero; constaddr(decode_loop) } end inst "skipnz $" do uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outdata; @control.set_uip_if_nonzero; constaddr(uip()+2) } uop { @control.set_uip; constaddr($eom) } uop { @decode.clear } decode_loop = uip() uop { @pc.increment; @pc.outaddr; @memory.outdata; @decode.decode } uop { @decode.outdata_needmore; @control.set_uip_if_nonzero; constaddr(decode_loop) } end inst "push $ #" do uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outaddr; @alu.sub; constdata(1) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } uop { @decode.outdata_b; @alu.outaddr; @memory.store } end inst "push $ $" do uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outaddr; @alu.sub; constdata(1) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } uop { @decode.outaddr_b; @rf.outdata; @tmp1.loaddata } uop { @tmp1.outdata; @alu.outaddr; @memory.store } end inst "pop $ $" do uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outaddr; @alu.add; constdata(1) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } uop { @alu.outaddr; @memory.outdata; @tmp0.loaddata } uop { @decode.outaddr_b; @tmp0.outdata; @rf.store } end def alu(op) inst "#{op} $ #" do uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @decode.outdata_b; @tmp0.outaddr; @alu.send(op) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } end inst "#{op} $ $" do uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @decode.outaddr_b; @rf.outdata; @tmp1.loaddata } uop { @tmp0.outaddr; @tmp1.outdata; @alu.send(op) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } end end alu :and alu :or alu :xor alu :add alu :sub alu :cmp inst "lshift $ #" do uop { @decode.outdata_b; @counter.load; @control.set_uip_if_zero; constaddr($eom) } uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outdata; @alu.xor; constaddr(0) } shiftloop = uip() uop { @counter.decrement; @alu.outdata; @alu.lshift; constaddr(0) } uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } end inst "lshift $ $" do uop { @decode.outaddr_b; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outdata; @counter.load; @control.set_uip_if_zero; constaddr($eom) } uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outdata; @alu.xor; constaddr(0) } shiftloop = uip() uop { @counter.decrement; @alu.outdata; @alu.lshift; constaddr(0) } uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } end inst "rshift $ #" do uop { @decode.outdata_b; @counter.load; @control.set_uip_if_zero; constaddr($eom) } uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outdata; @alu.xor; constaddr(0) } shiftloop = uip() uop { @counter.decrement; @alu.outdata; @alu.rshift; constaddr(0) } uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } end inst "rshift $ $" do uop { @decode.outaddr_b; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outdata; @counter.load; @control.set_uip_if_zero; constaddr($eom) } uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outdata; @alu.xor; constaddr(0) } shiftloop = uip() uop { @counter.decrement; @alu.outdata; @alu.rshift; constaddr(0) } uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } end inst "rshiftsign $ #" do uop { @decode.outdata_b; @counter.load; @control.set_uip_if_zero; constaddr($eom) } uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outdata; @alu.xor; constaddr(0) } shiftloop = uip() uop { @tmp0.outaddr; @counter.decrement; @alu.outdata; @alu.rshift } uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } end inst "rshiftsign $ $" do uop { @decode.outaddr_b; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outdata; @counter.load; @control.set_uip_if_zero; constaddr($eom) } uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @tmp0.outdata; @alu.xor; constaddr(0) } shiftloop = uip() uop { @tmp0.outaddr; @counter.decrement; @alu.outdata; @alu.rshift } uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } end inst "mul $ #" do uop { @alu.xor; constaddr(0); @control.outdata } uop { @decode.outdata_b; @counter.load; @control.set_uip_if_zero; constaddr(uip()+4) } uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } mulloop = uip() uop { @counter.decrement; @alu.outdata; @tmp0.outaddr; @alu.add } uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(mulloop) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } end inst "mul $ $" do uop { @alu.xor; constaddr(0); @control.outdata } uop { @decode.outaddr_a; @rf.outdata; @counter.load } uop { @counter.outdata; @control.set_uip_if_zero; constaddr(uip()+4) } uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } mulloop = uip() uop { @counter.decrement; @alu.outdata; @tmp0.outaddr; @alu.add } uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(mulloop) } uop { @decode.outaddr_a; @alu.outdata; @rf.store } end def cmpbit(name, bit) inst "#{name} $ #" do uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } uop { @decode.outdata_b; @tmp0.outaddr; @alu.cmp } uop { @alu.outdata; @alu.and; constaddr(1<