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

Subversion Repositories tinycpu

[/] [tinycpu/] [trunk/] [assembler/] [asm.rb] - Blame information for rev 41

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 39 earlz
PREFIX = "x\"";
2
SUFFIX = "\"";
3
SEPERATOR = ", ";
4 36 earlz
 
5
 
6
 
7
class OpcodeByte1
8
  attr_accessor :op, :register, :cond;
9
  def to_hex
10
    s = (op << 4 | register.number << 1 | cond).to_s(16);
11
    if s.length == 1
12
      "0"+s;
13
    elsif s.length == 0
14
      "00";
15
    else
16
      s
17
    end
18
  end
19
end
20 37 earlz
 
21 38 earlz
class OpcodeByte2
22
  attr_accessor :cond, :reg2, :useextra, :reg3;
23
  def to_hex
24 40 earlz
    s=(cond << 7 | reg2.number << 4 | useextra << 3 | reg3.number).to_s(16);
25 38 earlz
    if s.length == 1
26
      "0"+s;
27
    elsif s.length==0
28
      "00";
29
    else
30
      s;
31
    end
32
  end
33
end
34 36 earlz
 
35
 
36 35 earlz
class Register8
37
  attr_accessor :number
38
  def initialize(num)
39
        @number=num
40
  end
41
end
42 38 earlz
class OpcodeOption
43
  attr_accessor :number
44
  def initialize(num)
45
    @number=num;
46
  end
47
end
48 35 earlz
 
49 36 earlz
$iftr = 0; #0 for no condition, 1 for if TR, 2 for if not TR
50 37 earlz
$useextra = 0;
51 39 earlz
$position = 0;
52 36 earlz
 
53 39 earlz
def set_cond(o1, o2)
54
  if $iftr==0 then
55
    o1.cond=0;
56
    o2.cond=0;
57
  elsif $iftr==1 then
58
    o1.cond=1;
59
    o2.cond=0;
60
  else
61
    o1.cond=0;
62
    o2.cond=1;
63
  end
64
end
65
def output_op(value)
66
  printf PREFIX + value + SUFFIX;
67
  printf SEPERATOR;
68
  $position+=2;
69
end
70
 
71
 
72 35 earlz
def mov_r8_imm8(reg,imm)
73 36 earlz
  o = OpcodeByte1.new();
74
  o.op = 0;
75
  o.register=reg;
76
  if $iftr<2 then
77
    o.cond=$iftr;
78
  else
79
    raise "if_tr_notset is not allowed with this opcode";
80
  end
81 39 earlz
  output_op(o.to_hex.rjust(2,"0") + imm.to_s(16).rjust(2,"0"))
82 35 earlz
end
83 37 earlz
def mov_rm8_imm8(reg,imm)
84
  o=OpcodeByte1.new();
85
  o.op=1;
86
  o.register=reg;
87
  if $iftr<2 then
88
    o.cond=$iftr;
89
  else
90
    raise "if_tr_notset is not allowed with this opcode";
91
  end
92 39 earlz
  output_op(o.to_hex.rjust(2,"0") + imm.to_s(16).rjust(2,"0"));
93 37 earlz
end
94 39 earlz
 
95
def do_group_reg_reg(opcode,group,reg1,reg2)
96
  o1 = OpcodeByte1.new()
97
  o1.op=opcode;
98
  o1.register=reg1;
99
  o2 = OpcodeByte2.new()
100
  o2.useextra=$useextra;
101
  o2.reg2=reg2;
102
  o2.reg3=OpcodeOption.new(group); #opcode group
103
  set_cond(o1,o2)
104
  output_op(o1.to_hex.rjust(2,"0") + o2.to_hex.rjust(2,"0"))
105
end
106
def do_subgroup_reg(opcode,group,subgroup,reg1)
107
  o1 = OpcodeByte1.new()
108
  o1.op=opcode;
109
  o1.register=reg1;
110
  o2 = OpcodeByte2.new()
111
  o2.useextra=$useextra;
112
  o2.reg2=OpcodeOption.new(subgroup);
113
  o2.reg3=OpcodeOption.new(group); #opcode group
114
  set_cond(o1,o2)
115
  output_op(o1.to_hex.rjust(2,"0") + o2.to_hex.rjust(2,"0"))
116
end
117
 
118
def and_reg_reg(reg1, reg2)
119
  do_group_reg_reg(4,0,reg1,reg2)
120
end;
121
def or_reg_reg(reg1, reg2)
122
  do_group_reg_reg(4,1,reg1,reg2)
123
end;
124
def xor_reg_reg(reg1, reg2)
125
  do_group_reg_reg(4,2,reg1,reg2)
126
end;
127
def not_reg_reg(reg1, reg2)
128
  do_group_reg_reg(4,3,reg1,reg2)
129
end;
130
def lsh_reg_reg(reg1, reg2)
131
  do_group_reg_reg(4,4,reg1,reg2)
132
end;
133
def rsh_reg_reg(reg1, reg2)
134
  do_group_reg_reg(4,5,reg1,reg2)
135
end;
136
def lro_reg_reg(reg1, reg2)
137
  do_group_reg_reg(4,6,reg1,reg2)
138
end;
139
def rro_reg_reg(reg1, reg2)
140
  do_group_reg_reg(4,7,reg1,reg2)
141
end;
142
#comparisons
143
def cmpgt_reg_reg(reg1, reg2)
144
  do_group_reg_reg(3,0,reg1,reg2)
145
end;
146
def cmpgte_reg_reg(reg1, reg2)
147
  do_group_reg_reg(3,1,reg1,reg2)
148
end;
149
def cmplt_reg_reg(reg1, reg2)
150
  do_group_reg_reg(3,2,reg1,reg2)
151
end;
152
def cmplte_reg_reg(reg1, reg2)
153
  do_group_reg_reg(3,3,reg1,reg2)
154
end;
155
def cmpeq_reg_reg(reg1, reg2)
156
  do_group_reg_reg(3,4,reg1,reg2)
157
end;
158
def cmpneq_reg_reg(reg1, reg2)
159
  do_group_reg_reg(3,5,reg1,reg2)
160
end;
161
def cmpeq_reg_0(reg1)
162
  do_group_reg_reg(3,6,reg1,Register8.new(0)) #last arg isn't used
163
end;
164
def cmpneq_reg_0(reg1)
165
  do_group_reg_reg(3,7,reg1,Register8.new(0))
166
end;
167
 
168
def mov_reg_mreg(reg1, reg2)
169
  do_group_reg_reg(5,2,reg1,reg2)
170
end
171
def mov_mreg_reg(reg1, reg2)
172
  do_group_reg_reg(5,3,reg1,reg2)
173
end
174
def mov_reg_reg(reg1, reg2)
175
  do_group_reg_reg(5,1,reg1,reg2)
176
end
177
 
178 37 earlz
 
179 35 earlz
 
180
def mov(arg1,arg2)
181 37 earlz
  if arg1.kind_of? Register8 and arg2.kind_of? Integer and arg2<0x100 then
182
    mov_r8_imm8 arg1,arg2
183
  elsif arg1.kind_of? Array and arg2.kind_of? Integer and arg2<0x100 then
184 39 earlz
    if arg1.length>1 or arg1.length<1 or not arg1[0].kind_of? Register8 then
185 37 earlz
      raise "memory reference is not correct. Only a register is allowed";
186
    end
187
    reg=arg1[0];
188
    mov_rm8_imm8 reg, arg2
189 39 earlz
  elsif arg1.kind_of? Array and arg2.kind_of? Register8 then
190
    if arg1.length>1 or arg1.length<1 or not arg1[0].kind_of? Register8 then
191
      raise "memory reference is not correct. Only a register is allowed";
192
    end
193
    mov_mreg_reg arg1[0], arg2
194
  elsif arg1.kind_of? Register8 and arg2.kind_of? Array then
195
    if arg2.length>1 or arg2.length<1 or not arg2[0].kind_of? Register8 then
196
      raise "memory reference is not correct. Only a register is allowed";
197
    end
198 41 earlz
    mov_reg_mreg arg1,arg2[0]
199 39 earlz
  elsif arg1.kind_of? Register8 and arg2.kind_of? Register8 then
200
    mov_reg_reg arg1, arg2
201 37 earlz
  else
202
    raise "No suitable mov opcode found";
203
  end
204 35 earlz
end
205 39 earlz
def and_(arg1,arg2)
206
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
207
    and_reg_reg arg1,arg2
208
  else
209
    raise "No suitable and opcode found";
210
  end
211
end
212
def or_(arg1,arg2)
213
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
214
    or_reg_reg arg1,arg2
215
  else
216
    raise "No suitable or opcode found";
217
  end
218
end
219
def xor_(arg1,arg2)
220
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
221
    xor_reg_reg arg1,arg2
222
  else
223
    raise "No suitable xor opcode found";
224
  end
225
end
226
def not_(arg1,arg2)
227
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
228
    not_reg_reg arg1,arg2
229
  else
230
    raise "No suitable not opcode found";
231
  end
232
end
233
def rsh(arg1,arg2)
234
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
235
    rsh_reg_reg arg1,arg2
236
  else
237
    raise "No suitable rsh opcode found";
238
  end
239
end
240
def lsh(arg1,arg2)
241
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
242
    lsh_reg_reg arg1,arg2
243
  else
244
    raise "No suitable lsh opcode found";
245
  end
246
end
247
def rro(arg1,arg2)
248
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
249
    rro_reg_reg arg1,arg2
250
  else
251
    raise "No suitable rro opcode found";
252
  end
253
end
254
def lro(arg1,arg2)
255
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
256
    lro_reg_reg arg1,arg2
257
  else
258
    raise "No suitable lro opcode found";
259
  end
260
end
261
 
262
def cmpgt(arg1,arg2)
263
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
264
    cmpgt_reg_reg arg1,arg2
265
  else
266
    raise "No suitable cmpgt opcode found";
267
  end
268
end
269
def cmpgte(arg1,arg2)
270
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
271
    cmpgte_reg_reg arg1,arg2
272
  else
273
    raise "No suitable cmpgte opcode found";
274
  end
275
end
276
def cmplt(arg1,arg2)
277
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
278
    cmplt_reg_reg arg1,arg2
279
  else
280
    raise "No suitable cmplt opcode found";
281
  end
282
end
283
def cmplte(arg1,arg2)
284
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
285
    cmplte_reg_reg arg1,arg2
286
  else
287
    raise "No suitable cmplte opcode found";
288
  end
289
end
290
def cmpeq(arg1,arg2)
291
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
292
    cmpeq_reg_reg arg1,arg2
293
  elsif arg1.kind_of? Register8 and arg2.kind_of? Integer and arg2==0 then
294
    cmpeq_reg_0 arg1
295
  else
296
    raise "No suitable cmpeq opcode found";
297
  end
298
end
299
def cmpneq(arg1,arg2)
300
  if arg1.kind_of? Register8 and arg2.kind_of? Register8 then
301
    cmpneq_reg_reg arg1,arg2
302
  elsif arg1.kind_of? Register8 and arg2.kind_of? Integer and arg2==0 then
303
    cmpneq_reg_0 arg1
304
  else
305
    raise "No suitable cmpneq opcode found";
306
  end
307
end
308
 
309
def Label
310
  attr_accessor :name, :pos
311
  def initialize(name, pos)
312
    @name=name;
313
    @pos=pos;
314
  end
315
end
316
$labellist={}
317 41 earlz
def new_label(name)
318 39 earlz
  $labellist[name.to_s]=$position;
319
end
320
def lbl(name)
321 41 earlz
  $labellist[name.to_s];
322 39 earlz
end
323
 
324
 
325 36 earlz
def if_tr_set
326
  $iftr = 1
327
  yield
328
  $iftr = 0
329
end
330 35 earlz
 
331
 
332 36 earlz
r0=Register8.new(0)
333
r1=Register8.new(1)
334
r2=Register8.new(2)
335
r3=Register8.new(3)
336 38 earlz
r4=Register8.new(4)
337
r5=Register8.new(5)
338
sp=Register8.new(6)
339
ip=Register8.new(7)
340 36 earlz
 
341 38 earlz
 
342 36 earlz
#test code follows. Only do it here for convenience.. real usage should prefix assembly files with `require "asm.rb"`
343 39 earlz
 
344
 
345
#port0(0) is LED port0(1) is a button
346
 
347
mov r4, 1
348 41 earlz
mov r5, 0xFD
349
#mov r5, 0x01 #the port bitmask
350 39 earlz
mov [r4],r5
351
mov r3, 0
352 41 earlz
mov [r3], 0
353 39 earlz
mov r2, 0x02
354
#poll for button
355 41 earlz
new_label :loop
356 39 earlz
mov r0, [r3]
357
and_ r0, r2 #isolate just the button at pin 2
358
cmpneq r0, 0
359 36 earlz
if_tr_set{
360 39 earlz
  mov [r3], 0x01
361 36 earlz
}
362 39 earlz
cmpeq r0,0
363
if_tr_set{
364
  mov [r3], 0x00
365
}
366
mov ip, lbl(:loop)
367
 
368
printf("\n");
369
while $position<64
370
  printf("x\"0000\", ")
371
  $position+=2;
372
end
373
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.