Module: YTLJit::AssemblerUtilIAModrm

Included in:
AssemblerUtilIA
Defined in:
lib/ytljit/instruction_ia.rb

Instance Method Summary collapse

Instance Method Details

#modrm(inst, reg, rm, dst, src, src2 = nil) ⇒ Object



531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
# File 'lib/ytljit/instruction_ia.rb', line 531

def modrm(inst, reg, rm, dst, src, src2 = nil)
  case reg
  when Integer
    case rm
    when OpRegistor
      [[0b11000000 | ((reg & 7) << 3) | (rm.reg_no & 7)], "C"]

    when OpIndirect
      modrm_indirect(reg, rm)

    when Integer, OpImmidiate
      [[0b00000000 | ((reg & 7) << 3) | 5], "C"]

    else
      return nosupported_addressing_mode(inst, dst, src, src2)
    end

  when OpRegistor
    case rm
    when OpRegistor
      [[0b11000000 | ((reg.reg_no & 7) << 3) | (rm.reg_no & 7)], "C"]

    when OpIndirect
      modrm_indirect(reg, rm)
    end

  else
    return nosupported_addressing_mode(inst, dst, src, src2)
  end
end

#modrm_indirect(reg, rm) ⇒ Object



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
# File 'lib/ytljit/instruction_ia.rb', line 486

def modrm_indirect(reg, rm)
  regv = nil
  case reg
  when Integer
    regv = reg
    
  else
    regv = reg.value
  end

  rmdisp = rm.disp
  if rmdisp.class == OpImmidiate then
    rmdisp = rmdisp.value
  end

  case rmdisp
  when 0
    if rm.reg.is_a?(OpEBP) or 
        rm.reg.is_a?(OpRBP) or rm.reg.is_a?(OpR13) then
      modrm_indirect_off8(regv, rm.reg, 0)
    else
      fstb = 0b00000000 | ((regv & 7) << 3) | (rm.reg.reg_no & 7)
      if rm.reg.is_a?(OpESP) or 
          rm.reg.is_a?(OpRSP) or rm.reg.is_a?(OpR12) then
        [[fstb, 0x24], "C2"]
      else
        [[fstb], "C"]
      end
    end
    
  when OpImmidiate8
    modrm_indirect_off8(regv, rm.reg, rmdisp.value)
    
  when OpImmidiate32
    modrm_indirect_off32(regv, rm.reg, rmdisp.value)

  when Integer
    if small_integer_8bit?(rmdisp.abs) then
      modrm_indirect_off8(regv, rm.reg, rmdisp)
    else
      modrm_indirect_off32(regv, rm.reg, rmdisp)
    end
  end
end

#modrm_indirect_off32(regv, rm_reg, rm_disp) ⇒ Object



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

def modrm_indirect_off32(regv, rm_reg, rm_disp)
  fstb = 0b10000000 | ((regv & 7) << 3) | (rm_reg.reg_no & 7)
  if rm_reg.is_a?(OpESP) or 
      rm_reg.is_a?(OpRSP) or rm_reg.is_a?(OpR12) then
    [[fstb, 0b00100100, rm_disp], "C2L"]
  else
    [[fstb, rm_disp], "CL"]
  end
end

#modrm_indirect_off8(regv, rm_reg, rm_disp) ⇒ Object



476
477
478
479
480
481
482
483
484
# File 'lib/ytljit/instruction_ia.rb', line 476

def modrm_indirect_off8(regv, rm_reg, rm_disp)
  fstb = 0b01000000 | ((regv & 7) << 3) | (rm_reg.reg_no & 7)
  if rm_reg.is_a?(OpESP) or 
      rm_reg.is_a?(OpRSP) or rm_reg.is_a?(OpR12) then
    [[fstb, 0b00100100, rm_disp], "C3"]
  else
    [[fstb, rm_disp], "CC"]
  end
end

#small_integer_32bit?(num) ⇒ Boolean

Returns:

  • (Boolean)


461
462
463
464
# File 'lib/ytljit/instruction_ia.rb', line 461

def small_integer_32bit?(num)
  num = (num & 0x7fff_ffff_ffff_ffff) - (num & 0x8000_0000_0000_0000)
  num.abs < 0x7fff_ffff
end

#small_integer_8bit?(num) ⇒ Boolean

Returns:

  • (Boolean)


456
457
458
459
# File 'lib/ytljit/instruction_ia.rb', line 456

def small_integer_8bit?(num)
  num = (num & 0x7fff_ffff) - (num & 0x8000_0000)
  num.abs < 0x7f
end