Class: YTLJit::VM::CompileContext

Inherits:
Object
  • Object
show all
Includes:
AbsArch
Defined in:
lib/ytljit/vm_codegen.rb

Constant Summary

Constants included from AbsArch

AbsArch::AL, AbsArch::BL, AbsArch::CL, AbsArch::DL, AbsArch::FUNC_ARG, AbsArch::FUNC_ARG_YTL, AbsArch::FUNC_FLOAT_ARG, AbsArch::FUNC_FLOAT_ARG_YTL, AbsArch::INDIRECT_BPR, AbsArch::INDIRECT_RETR, AbsArch::INDIRECT_SPR, AbsArch::INDIRECT_TMPR, AbsArch::INDIRECT_TMPR2, AbsArch::INDIRECT_TMPR3

Constants included from SSE

SSE::XMM0, SSE::XMM1, SSE::XMM2, SSE::XMM3, SSE::XMM4, SSE::XMM5, SSE::XMM6, SSE::XMM7

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tnode) ⇒ CompileContext

Returns a new instance of CompileContext.



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/ytljit/vm_codegen.rb', line 256

def initialize(tnode)
  @top_node = tnode
  @prev_context = nil
  @code_space = nil

  # Signature of current compiling method
  # It is array, because method may be nest.
  @current_method_signature = []
  
  # RETR(EAX, RAX) or RETFR(STO, XM0) or Immdiage object
  @ret_reg = RETR
  @ret_reg2 = RETR
  @ret_node = nil
#        @depth_reg = {}
  @depth_reg = Hash.new(0)
  @stack_content = []
  @reg_content = {}

  # Use only type inference compile mode
  @slf = nil

  # Options from user
  @options = {}
end

Instance Attribute Details

#code_spaceObject (readonly)

Returns the value of attribute code_space.



283
284
285
# File 'lib/ytljit/vm_codegen.rb', line 283

def code_space
  @code_space
end

#current_method_signatureObject (readonly)

Returns the value of attribute current_method_signature.



285
286
287
# File 'lib/ytljit/vm_codegen.rb', line 285

def current_method_signature
  @current_method_signature
end

#depth_regObject (readonly)

Returns the value of attribute depth_reg.



287
288
289
# File 'lib/ytljit/vm_codegen.rb', line 287

def depth_reg
  @depth_reg
end

#optionsObject

Returns the value of attribute options.



297
298
299
# File 'lib/ytljit/vm_codegen.rb', line 297

def options
  @options
end

#prev_contextObject

Returns the value of attribute prev_context.



282
283
284
# File 'lib/ytljit/vm_codegen.rb', line 282

def prev_context
  @prev_context
end

#reg_contentObject (readonly)

Returns the value of attribute reg_content.



292
293
294
# File 'lib/ytljit/vm_codegen.rb', line 292

def reg_content
  @reg_content
end

#ret_nodeObject

Returns the value of attribute ret_node.



290
291
292
# File 'lib/ytljit/vm_codegen.rb', line 290

def ret_node
  @ret_node
end

#ret_regObject

Returns the value of attribute ret_reg.



288
289
290
# File 'lib/ytljit/vm_codegen.rb', line 288

def ret_reg
  @ret_reg
end

#ret_reg2Object

Returns the value of attribute ret_reg2.



289
290
291
# File 'lib/ytljit/vm_codegen.rb', line 289

def ret_reg2
  @ret_reg2
end

#slfObject

Returns the value of attribute slf.



295
296
297
# File 'lib/ytljit/vm_codegen.rb', line 295

def slf
  @slf
end

#stack_contentObject

Returns the value of attribute stack_content.



293
294
295
# File 'lib/ytljit/vm_codegen.rb', line 293

def stack_content
  @stack_content
end

#top_nodeObject (readonly)

Returns the value of attribute top_node.



281
282
283
# File 'lib/ytljit/vm_codegen.rb', line 281

def top_node
  @top_node
end

Instance Method Details

#assemblerObject



383
384
385
# File 'lib/ytljit/vm_codegen.rb', line 383

def assembler
  @top_node.asm_tab[@code_space]
end

#cpustack_pop(reg) ⇒ Object



342
343
344
345
346
347
# File 'lib/ytljit/vm_codegen.rb', line 342

def cpustack_pop(reg)
  cont = @stack_content.pop
  if !cont.is_a?(OpRegistor) then
    @reg_content[reg] = cont
  end
end

#cpustack_popn(num) ⇒ Object



364
365
366
367
368
369
# File 'lib/ytljit/vm_codegen.rb', line 364

def cpustack_popn(num)
  wsiz = AsmType::MACHINE_WORD.size
  (num / wsiz).times do |i|
    @stack_content.pop
  end
end

#cpustack_push(reg) ⇒ Object



334
335
336
337
338
339
340
# File 'lib/ytljit/vm_codegen.rb', line 334

def cpustack_push(reg)
  if @reg_content[reg] then
    @stack_content.push @reg_content[reg]
  else
    @stack_content.push reg
  end
end

#cpustack_pushn(num) ⇒ Object



357
358
359
360
361
362
# File 'lib/ytljit/vm_codegen.rb', line 357

def cpustack_pushn(num)
  wsiz = AsmType::MACHINE_WORD.size
  (num / wsiz).times do |i|
    @stack_content.push 1.2
  end
end

#cpustack_setn(offset, val) ⇒ Object



349
350
351
352
353
354
355
# File 'lib/ytljit/vm_codegen.rb', line 349

def cpustack_setn(offset, val)
  if offset >= -@stack_content.size then
    @stack_content[offset] = val
  else
    # Modify previous stack (maybe as arguments)
  end
end

#end_arg_reg(kind = FUNC_ARG) ⇒ Object



478
479
480
481
482
483
484
485
486
487
# File 'lib/ytljit/vm_codegen.rb', line 478

def end_arg_reg(kind = FUNC_ARG)
  asm = assembler
  gen = asm.generator
  used_arg_tab = gen.funcarg_info.used_arg_tab
  if used_arg_tab.last then
    used_arg_tab.last.keys.reverse.each do |rno|
      end_using_reg(kind[rno])
    end
  end
end

#end_using_reg(reg) ⇒ Object



443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
# File 'lib/ytljit/vm_codegen.rb', line 443

def end_using_reg(reg)
  case reg
  when OpRegistor
    if reg != TMPR and reg != XMM0 then
      end_using_reg_aux(reg)
    end

  when OpIndirect
    case reg.reg 
    when BPR

    else
      end_using_reg_aux(reg.reg)
    end

  when FunctionArgument
    regdst = reg.dst_opecode
    if regdst.is_a?(OpRegistor) then
      end_using_reg_aux(regdst)
    end
  end
end

#end_using_reg_aux(reg) ⇒ Object



426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
# File 'lib/ytljit/vm_codegen.rb', line 426

def end_using_reg_aux(reg)
  if @depth_reg[reg] then
    @depth_reg[reg] -= 1
  else
    raise "Not saved reg #{reg}"
  end
  if @depth_reg[reg] != -1 then
    assembler.with_retry do
      assembler.pop(reg)
      cpustack_pop(reg)
    end
  else
    @depth_reg[reg] = nil
    @reg_content.delete(reg)
  end
end

#pop_signatureObject



500
501
502
# File 'lib/ytljit/vm_codegen.rb', line 500

def pop_signature
  @current_method_signature.pop
end

#push_signature(signode, method) ⇒ Object



493
494
495
496
497
498
# File 'lib/ytljit/vm_codegen.rb', line 493

def push_signature(signode, method)
  sig = signode.map { |enode|
    enode.decide_type_once(to_signature)
  }
  @current_method_signature.push sig
end

#reset_using_regObject



387
388
389
# File 'lib/ytljit/vm_codegen.rb', line 387

def reset_using_reg
  @depth_reg = Hash.new(0)
end

#set_code_space(cs) ⇒ Object



371
372
373
374
375
376
377
378
379
380
381
# File 'lib/ytljit/vm_codegen.rb', line 371

def set_code_space(cs)
  oldcs = @code_space
  @top_node.add_code_space(@code_space, cs)
  @code_space = cs
  asm = @top_node.asm_tab[cs]
  if asm == nil then
    @top_node.asm_tab[cs] = Assembler.new(cs)
  end

  oldcs
end

#set_reg_content(dst, val) ⇒ Object



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/ytljit/vm_codegen.rb', line 299

def set_reg_content(dst, val)
  if dst.is_a?(FunctionArgument) then
    dst = dst.dst_opecode
  end
  if dst.is_a?(OpRegistor) then
    if val.is_a?(OpRegistor) and @reg_content[val] then
      @reg_content[dst] = @reg_content[val]
    else
      @reg_content[dst] = val
    end
  elsif dst.is_a?(OpIndirect) then
    wsiz = AsmType::MACHINE_WORD.size
    if dst.reg == SPR then
      if val.is_a?(OpRegistor) and @reg_content[val] then
        cpustack_setn(dst.disp.value / wsiz, @reg_content[val])
      else
        cpustack_setn(dst.disp.value / wsiz, val)
      end
    end
    if dst.reg == BPR then
      if val.is_a?(OpRegistor) and @reg_content[val] then
        cpustack_setn(-dst.disp.value / wsiz + 3, @reg_content[val])
      else
        cpustack_setn(-dst.disp.value / wsiz + 3, val)
      end
    end
  elsif dst.is_a?(OpImmidiate) then
    # do nothing and legal

  else
#          pp "foo"
#          pp dst
  end
end

#start_arg_reg(kind = FUNC_ARG) ⇒ Object



466
467
468
469
470
471
472
473
474
475
476
# File 'lib/ytljit/vm_codegen.rb', line 466

def start_arg_reg(kind = FUNC_ARG)
  asm = assembler
  gen = asm.generator
  used_arg_tab = gen.funcarg_info.used_arg_tab
  if used_arg_tab.last then
#          p "#{used_arg_tab.last.keys} #{caller[0]} #{@name}"
    used_arg_tab.last.keys.each do |rno|
      start_using_reg(kind[rno])
    end
  end
end

#start_using_reg(reg) ⇒ Object



403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
# File 'lib/ytljit/vm_codegen.rb', line 403

def start_using_reg(reg)
  case reg
  when OpRegistor
    if reg != TMPR and reg != XMM0 then
      start_using_reg_aux(reg)
    end

  when OpIndirect
    case reg.reg 
    when BPR

    else
      start_using_reg_aux(reg.reg)
    end

  when FunctionArgument
    regdst = reg.dst_opecode
    if regdst.is_a?(OpRegistor)
      start_using_reg_aux(regdst)
    end
  end
end

#start_using_reg_aux(reg) ⇒ Object



391
392
393
394
395
396
397
398
399
400
401
# File 'lib/ytljit/vm_codegen.rb', line 391

def start_using_reg_aux(reg)
  if @depth_reg[reg] then
    assembler.with_retry do
      assembler.push(reg)
      cpustack_push(reg)
    end
  else
    @depth_reg[reg] = 0
  end
  @depth_reg[reg] += 1
end

#to_signature(offset = -1)) ⇒ Object



489
490
491
# File 'lib/ytljit/vm_codegen.rb', line 489

def to_signature(offset = -1)
  @current_method_signature[offset]
end