OpenCores
URL https://opencores.org/ocsvn/tinycpu/tinycpu/trunk

Subversion Repositories tinycpu

[/] [tinycpu/] [trunk/] [assembler/] [asm.rb] - Diff between revs 40 and 41

Only display areas with differences | Details | Blame | View Log

Rev 40 Rev 41
PREFIX = "x\"";
PREFIX = "x\"";
SUFFIX = "\"";
SUFFIX = "\"";
SEPERATOR = ", ";
SEPERATOR = ", ";
class OpcodeByte1
class OpcodeByte1
  attr_accessor :op, :register, :cond;
  attr_accessor :op, :register, :cond;
  def to_hex
  def to_hex
    s = (op << 4 | register.number << 1 | cond).to_s(16);
    s = (op << 4 | register.number << 1 | cond).to_s(16);
    if s.length == 1
    if s.length == 1
      "0"+s;
      "0"+s;
    elsif s.length == 0
    elsif s.length == 0
      "00";
      "00";
    else
    else
      s
      s
    end
    end
  end
  end
end
end
class OpcodeByte2
class OpcodeByte2
  attr_accessor :cond, :reg2, :useextra, :reg3;
  attr_accessor :cond, :reg2, :useextra, :reg3;
  def to_hex
  def to_hex
    s=(cond << 7 | reg2.number << 4 | useextra << 3 | reg3.number).to_s(16);
    s=(cond << 7 | reg2.number << 4 | useextra << 3 | reg3.number).to_s(16);
    if s.length == 1
    if s.length == 1
      "0"+s;
      "0"+s;
    elsif s.length==0
    elsif s.length==0
      "00";
      "00";
    else
    else
      s;
      s;
    end
    end
  end
  end
end
end
class Register8
class Register8
  attr_accessor :number
  attr_accessor :number
  def initialize(num)
  def initialize(num)
        @number=num
        @number=num
  end
  end
end
end
class OpcodeOption
class OpcodeOption
  attr_accessor :number
  attr_accessor :number
  def initialize(num)
  def initialize(num)
    @number=num;
    @number=num;
  end
  end
end
end
$iftr = 0; #0 for no condition, 1 for if TR, 2 for if not TR
$iftr = 0; #0 for no condition, 1 for if TR, 2 for if not TR
$useextra = 0;
$useextra = 0;
$position = 0;
$position = 0;
def set_cond(o1, o2)
def set_cond(o1, o2)
  if $iftr==0 then
  if $iftr==0 then
    o1.cond=0;
    o1.cond=0;
    o2.cond=0;
    o2.cond=0;
  elsif $iftr==1 then
  elsif $iftr==1 then
    o1.cond=1;
    o1.cond=1;
    o2.cond=0;
    o2.cond=0;
  else
  else
    o1.cond=0;
    o1.cond=0;
    o2.cond=1;
    o2.cond=1;
  end
  end
end
end
def output_op(value)
def output_op(value)
  printf PREFIX + value + SUFFIX;
  printf PREFIX + value + SUFFIX;
  printf SEPERATOR;
  printf SEPERATOR;
  $position+=2;
  $position+=2;
end
end
def mov_r8_imm8(reg,imm)
def mov_r8_imm8(reg,imm)
  o = OpcodeByte1.new();
  o = OpcodeByte1.new();
  o.op = 0;
  o.op = 0;
  o.register=reg;
  o.register=reg;
  if $iftr<2 then
  if $iftr<2 then
    o.cond=$iftr;
    o.cond=$iftr;
  else
  else
    raise "if_tr_notset is not allowed with this opcode";
    raise "if_tr_notset is not allowed with this opcode";
  end
  end
  output_op(o.to_hex.rjust(2,"0") + imm.to_s(16).rjust(2,"0"))
  output_op(o.to_hex.rjust(2,"0") + imm.to_s(16).rjust(2,"0"))
end
end
def mov_rm8_imm8(reg,imm)
def mov_rm8_imm8(reg,imm)
  o=OpcodeByte1.new();
  o=OpcodeByte1.new();
  o.op=1;
  o.op=1;
  o.register=reg;
  o.register=reg;
  if $iftr<2 then
  if $iftr<2 then
    o.cond=$iftr;
    o.cond=$iftr;
  else
  else
    raise "if_tr_notset is not allowed with this opcode";
    raise "if_tr_notset is not allowed with this opcode";
  end
  end
  output_op(o.to_hex.rjust(2,"0") + imm.to_s(16).rjust(2,"0"));
  output_op(o.to_hex.rjust(2,"0") + imm.to_s(16).rjust(2,"0"));
end
end
def do_group_reg_reg(opcode,group,reg1,reg2)
def do_group_reg_reg(opcode,group,reg1,reg2)
  o1 = OpcodeByte1.new()
  o1 = OpcodeByte1.new()
  o1.op=opcode;
  o1.op=opcode;
  o1.register=reg1;
  o1.register=reg1;
  o2 = OpcodeByte2.new()
  o2 = OpcodeByte2.new()
  o2.useextra=$useextra;
  o2.useextra=$useextra;
  o2.reg2=reg2;
  o2.reg2=reg2;
  o2.reg3=OpcodeOption.new(group); #opcode group
  o2.reg3=OpcodeOption.new(group); #opcode group
  set_cond(o1,o2)
  set_cond(o1,o2)
  output_op(o1.to_hex.rjust(2,"0") + o2.to_hex.rjust(2,"0"))
  output_op(o1.to_hex.rjust(2,"0") + o2.to_hex.rjust(2,"0"))
end
end
def do_subgroup_reg(opcode,group,subgroup,reg1)
def do_subgroup_reg(opcode,group,subgroup,reg1)
  o1 = OpcodeByte1.new()
  o1 = OpcodeByte1.new()
  o1.op=opcode;
  o1.op=opcode;
  o1.register=reg1;
  o1.register=reg1;
  o2 = OpcodeByte2.new()
  o2 = OpcodeByte2.new()
  o2.useextra=$useextra;
  o2.useextra=$useextra;
  o2.reg2=OpcodeOption.new(subgroup);
  o2.reg2=OpcodeOption.new(subgroup);
  o2.reg3=OpcodeOption.new(group); #opcode group
  o2.reg3=OpcodeOption.new(group); #opcode group
  set_cond(o1,o2)
  set_cond(o1,o2)
  output_op(o1.to_hex.rjust(2,"0") + o2.to_hex.rjust(2,"0"))
  output_op(o1.to_hex.rjust(2,"0") + o2.to_hex.rjust(2,"0"))
end
end
def and_reg_reg(reg1, reg2)
def and_reg_reg(reg1, reg2)
  do_group_reg_reg(4,0,reg1,reg2)
  do_group_reg_reg(4,0,reg1,reg2)
end;
end;
def or_reg_reg(reg1, reg2)
def or_reg_reg(reg1, reg2)
  do_group_reg_reg(4,1,reg1,reg2)
  do_group_reg_reg(4,1,reg1,reg2)
end;
end;
def xor_reg_reg(reg1, reg2)
def xor_reg_reg(reg1, reg2)
  do_group_reg_reg(4,2,reg1,reg2)
  do_group_reg_reg(4,2,reg1,reg2)
end;
end;
def not_reg_reg(reg1, reg2)
def not_reg_reg(reg1, reg2)
  do_group_reg_reg(4,3,reg1,reg2)
  do_group_reg_reg(4,3,reg1,reg2)
end;
end;
def lsh_reg_reg(reg1, reg2)
def lsh_reg_reg(reg1, reg2)
  do_group_reg_reg(4,4,reg1,reg2)
  do_group_reg_reg(4,4,reg1,reg2)
end;
end;
def rsh_reg_reg(reg1, reg2)
def rsh_reg_reg(reg1, reg2)
  do_group_reg_reg(4,5,reg1,reg2)
  do_group_reg_reg(4,5,reg1,reg2)
end;
end;
def lro_reg_reg(reg1, reg2)
def lro_reg_reg(reg1, reg2)
  do_group_reg_reg(4,6,reg1,reg2)
  do_group_reg_reg(4,6,reg1,reg2)
end;
end;
def rro_reg_reg(reg1, reg2)
def rro_reg_reg(reg1, reg2)
  do_group_reg_reg(4,7,reg1,reg2)
  do_group_reg_reg(4,7,reg1,reg2)
end;
end;
#comparisons
#comparisons
def cmpgt_reg_reg(reg1, reg2)
def cmpgt_reg_reg(reg1, reg2)
  do_group_reg_reg(3,0,reg1,reg2)
  do_group_reg_reg(3,0,reg1,reg2)
end;
end;
def cmpgte_reg_reg(reg1, reg2)
def cmpgte_reg_reg(reg1, reg2)
  do_group_reg_reg(3,1,reg1,reg2)
  do_group_reg_reg(3,1,reg1,reg2)
end;
end;
def cmplt_reg_reg(reg1, reg2)
def cmplt_reg_reg(reg1, reg2)
  do_group_reg_reg(3,2,reg1,reg2)
  do_group_reg_reg(3,2,reg1,reg2)
end;
end;
def cmplte_reg_reg(reg1, reg2)
def cmplte_reg_reg(reg1, reg2)
  do_group_reg_reg(3,3,reg1,reg2)
  do_group_reg_reg(3,3,reg1,reg2)
end;
end;
def cmpeq_reg_reg(reg1, reg2)
def cmpeq_reg_reg(reg1, reg2)
  do_group_reg_reg(3,4,reg1,reg2)
  do_group_reg_reg(3,4,reg1,reg2)
end;
end;
def cmpneq_reg_reg(reg1, reg2)
def cmpneq_reg_reg(reg1, reg2)
  do_group_reg_reg(3,5,reg1,reg2)
  do_group_reg_reg(3,5,reg1,reg2)
end;
end;
def cmpeq_reg_0(reg1)
def cmpeq_reg_0(reg1)
  do_group_reg_reg(3,6,reg1,Register8.new(0)) #last arg isn't used
  do_group_reg_reg(3,6,reg1,Register8.new(0)) #last arg isn't used
end;
end;
def cmpneq_reg_0(reg1)
def cmpneq_reg_0(reg1)
  do_group_reg_reg(3,7,reg1,Register8.new(0))
  do_group_reg_reg(3,7,reg1,Register8.new(0))
end;
end;
def mov_reg_mreg(reg1, reg2)
def mov_reg_mreg(reg1, reg2)
  do_group_reg_reg(5,2,reg1,reg2)
  do_group_reg_reg(5,2,reg1,reg2)
end
end
def mov_mreg_reg(reg1, reg2)
def mov_mreg_reg(reg1, reg2)
  do_group_reg_reg(5,3,reg1,reg2)
  do_group_reg_reg(5,3,reg1,reg2)
end
end
def mov_reg_reg(reg1, reg2)
def mov_reg_reg(reg1, reg2)
  do_group_reg_reg(5,1,reg1,reg2)
  do_group_reg_reg(5,1,reg1,reg2)
end
end
def mov(arg1,arg2)
def mov(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Integer and arg2<0x100 then
  if arg1.kind_of? Register8 and arg2.kind_of? Integer and arg2<0x100 then
    mov_r8_imm8 arg1,arg2
    mov_r8_imm8 arg1,arg2
  elsif arg1.kind_of? Array and arg2.kind_of? Integer and arg2<0x100 then
  elsif arg1.kind_of? Array and arg2.kind_of? Integer and arg2<0x100 then
    if arg1.length>1 or arg1.length<1 or not arg1[0].kind_of? Register8 then
    if arg1.length>1 or arg1.length<1 or not arg1[0].kind_of? Register8 then
      raise "memory reference is not correct. Only a register is allowed";
      raise "memory reference is not correct. Only a register is allowed";
    end
    end
    reg=arg1[0];
    reg=arg1[0];
    mov_rm8_imm8 reg, arg2
    mov_rm8_imm8 reg, arg2
  elsif arg1.kind_of? Array and arg2.kind_of? Register8 then
  elsif arg1.kind_of? Array and arg2.kind_of? Register8 then
    if arg1.length>1 or arg1.length<1 or not arg1[0].kind_of? Register8 then
    if arg1.length>1 or arg1.length<1 or not arg1[0].kind_of? Register8 then
      raise "memory reference is not correct. Only a register is allowed";
      raise "memory reference is not correct. Only a register is allowed";
    end
    end
    mov_mreg_reg arg1[0], arg2
    mov_mreg_reg arg1[0], arg2
  elsif arg1.kind_of? Register8 and arg2.kind_of? Array then
  elsif arg1.kind_of? Register8 and arg2.kind_of? Array then
    if arg2.length>1 or arg2.length<1 or not arg2[0].kind_of? Register8 then
    if arg2.length>1 or arg2.length<1 or not arg2[0].kind_of? Register8 then
      raise "memory reference is not correct. Only a register is allowed";
      raise "memory reference is not correct. Only a register is allowed";
    end
    end
    mov_mreg_reg arg1,arg2[0]
    mov_reg_mreg arg1,arg2[0]
  elsif arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  elsif arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    mov_reg_reg arg1, arg2
    mov_reg_reg arg1, arg2
  else
  else
    raise "No suitable mov opcode found";
    raise "No suitable mov opcode found";
  end
  end
end
end
def and_(arg1,arg2)
def and_(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    and_reg_reg arg1,arg2
    and_reg_reg arg1,arg2
  else
  else
    raise "No suitable and opcode found";
    raise "No suitable and opcode found";
  end
  end
end
end
def or_(arg1,arg2)
def or_(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    or_reg_reg arg1,arg2
    or_reg_reg arg1,arg2
  else
  else
    raise "No suitable or opcode found";
    raise "No suitable or opcode found";
  end
  end
end
end
def xor_(arg1,arg2)
def xor_(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    xor_reg_reg arg1,arg2
    xor_reg_reg arg1,arg2
  else
  else
    raise "No suitable xor opcode found";
    raise "No suitable xor opcode found";
  end
  end
end
end
def not_(arg1,arg2)
def not_(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    not_reg_reg arg1,arg2
    not_reg_reg arg1,arg2
  else
  else
    raise "No suitable not opcode found";
    raise "No suitable not opcode found";
  end
  end
end
end
def rsh(arg1,arg2)
def rsh(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    rsh_reg_reg arg1,arg2
    rsh_reg_reg arg1,arg2
  else
  else
    raise "No suitable rsh opcode found";
    raise "No suitable rsh opcode found";
  end
  end
end
end
def lsh(arg1,arg2)
def lsh(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    lsh_reg_reg arg1,arg2
    lsh_reg_reg arg1,arg2
  else
  else
    raise "No suitable lsh opcode found";
    raise "No suitable lsh opcode found";
  end
  end
end
end
def rro(arg1,arg2)
def rro(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    rro_reg_reg arg1,arg2
    rro_reg_reg arg1,arg2
  else
  else
    raise "No suitable rro opcode found";
    raise "No suitable rro opcode found";
  end
  end
end
end
def lro(arg1,arg2)
def lro(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    lro_reg_reg arg1,arg2
    lro_reg_reg arg1,arg2
  else
  else
    raise "No suitable lro opcode found";
    raise "No suitable lro opcode found";
  end
  end
end
end
def cmpgt(arg1,arg2)
def cmpgt(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    cmpgt_reg_reg arg1,arg2
    cmpgt_reg_reg arg1,arg2
  else
  else
    raise "No suitable cmpgt opcode found";
    raise "No suitable cmpgt opcode found";
  end
  end
end
end
def cmpgte(arg1,arg2)
def cmpgte(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    cmpgte_reg_reg arg1,arg2
    cmpgte_reg_reg arg1,arg2
  else
  else
    raise "No suitable cmpgte opcode found";
    raise "No suitable cmpgte opcode found";
  end
  end
end
end
def cmplt(arg1,arg2)
def cmplt(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    cmplt_reg_reg arg1,arg2
    cmplt_reg_reg arg1,arg2
  else
  else
    raise "No suitable cmplt opcode found";
    raise "No suitable cmplt opcode found";
  end
  end
end
end
def cmplte(arg1,arg2)
def cmplte(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    cmplte_reg_reg arg1,arg2
    cmplte_reg_reg arg1,arg2
  else
  else
    raise "No suitable cmplte opcode found";
    raise "No suitable cmplte opcode found";
  end
  end
end
end
def cmpeq(arg1,arg2)
def cmpeq(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    cmpeq_reg_reg arg1,arg2
    cmpeq_reg_reg arg1,arg2
  elsif arg1.kind_of? Register8 and arg2.kind_of? Integer and arg2==0 then
  elsif arg1.kind_of? Register8 and arg2.kind_of? Integer and arg2==0 then
    cmpeq_reg_0 arg1
    cmpeq_reg_0 arg1
  else
  else
    raise "No suitable cmpeq opcode found";
    raise "No suitable cmpeq opcode found";
  end
  end
end
end
def cmpneq(arg1,arg2)
def cmpneq(arg1,arg2)
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
    cmpneq_reg_reg arg1,arg2
    cmpneq_reg_reg arg1,arg2
  elsif arg1.kind_of? Register8 and arg2.kind_of? Integer and arg2==0 then
  elsif arg1.kind_of? Register8 and arg2.kind_of? Integer and arg2==0 then
    cmpneq_reg_0 arg1
    cmpneq_reg_0 arg1
  else
  else
    raise "No suitable cmpneq opcode found";
    raise "No suitable cmpneq opcode found";
  end
  end
end
end
def Label
def Label
  attr_accessor :name, :pos
  attr_accessor :name, :pos
  def initialize(name, pos)
  def initialize(name, pos)
    @name=name;
    @name=name;
    @pos=pos;
    @pos=pos;
  end
  end
end
end
$labellist={}
$labellist={}
def label(name)
def new_label(name)
  $labellist[name.to_s]=$position;
  $labellist[name.to_s]=$position;
end
end
def lbl(name)
def lbl(name)
  $labellist[name.to_s]=$position;
  $labellist[name.to_s];
end
end
def if_tr_set
def if_tr_set
  $iftr = 1
  $iftr = 1
  yield
  yield
  $iftr = 0
  $iftr = 0
end
end
r0=Register8.new(0)
r0=Register8.new(0)
r1=Register8.new(1)
r1=Register8.new(1)
r2=Register8.new(2)
r2=Register8.new(2)
r3=Register8.new(3)
r3=Register8.new(3)
r4=Register8.new(4)
r4=Register8.new(4)
r5=Register8.new(5)
r5=Register8.new(5)
sp=Register8.new(6)
sp=Register8.new(6)
ip=Register8.new(7)
ip=Register8.new(7)
#test code follows. Only do it here for convenience.. real usage should prefix assembly files with `require "asm.rb"`
#test code follows. Only do it here for convenience.. real usage should prefix assembly files with `require "asm.rb"`
#port0(0) is LED port0(1) is a button
#port0(0) is LED port0(1) is a button
mov r4, 1
mov r4, 1
mov r5, 0x01 #the port bitmask
mov r5, 0xFD
 
#mov r5, 0x01 #the port bitmask
mov [r4],r5
mov [r4],r5
mov r3, 0
mov r3, 0
 
mov [r3], 0
mov r2, 0x02
mov r2, 0x02
#poll for button
#poll for button
label :loop
new_label :loop
mov r0, [r3]
mov r0, [r3]
and_ r0, r2 #isolate just the button at pin 2
and_ r0, r2 #isolate just the button at pin 2
cmpneq r0, 0
cmpneq r0, 0
if_tr_set{
if_tr_set{
  mov [r3], 0x01
  mov [r3], 0x01
}
}
cmpeq r0,0
cmpeq r0,0
if_tr_set{
if_tr_set{
  mov [r3], 0x00
  mov [r3], 0x00
}
}
mov ip, lbl(:loop)
mov ip, lbl(:loop)
printf("\n");
printf("\n");
while $position<64
while $position<64
  printf("x\"0000\", ")
  printf("x\"0000\", ")
  $position+=2;
  $position+=2;
end
end
puts "\nsize:" + $position.to_s
puts "\nsize:" + $position.to_s
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.