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



522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
# File 'lib/ytljit/instruction_ia.rb', line 522

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



484
485
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
# File 'lib/ytljit/instruction_ia.rb', line 484

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

  case rm.disp
  when 0
    if rm.reg.is_a?(OpEBP) or rm.reg.is_a?(OpRBP) 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)  then
        [[fstb, 0x24], "C2"]
      else
        [[fstb], "C"]
      end
    end
    
  when OpImmidiate8
    modrm_indirect_off8(regv, rm.reg, rm.disp.value)
    
  when OpImmidiate32
    modrm_indirect_off32(regv, rm.reg, rm.disp.value)

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

#modrm_indirect_off32(regv, rm_reg, rm_disp) ⇒ Object



466
467
468
469
470
471
472
473
# 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) then
    [[fstb, 0b00100100, rm_disp], "C2L"]
  else
    [[fstb, rm_disp], "CL"]
  end
end

#modrm_indirect_off8(regv, rm_reg, rm_disp) ⇒ Object



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

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) 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