Module: YTLJit::AssemblerUtilIA

Includes:
AssemblerUtilIAModrm
Included in:
GeneratorIABinary
Defined in:
lib/ytljit/instruction_ia.rb

Instance Method Summary collapse

Methods included from AssemblerUtilIAModrm

#modrm, #modrm_indirect, #modrm_indirect_off32, #modrm_indirect_off8, #small_integer_32bit?, #small_integer_8bit?

Instance Method Details

#common_arithxmm(dst, src, op0, op1, inst) ⇒ Object



742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
# File 'lib/ytljit/instruction_ia.rb', line 742

def common_arithxmm(dst, src, op0, op1, inst)
  case dst
  when OpRegXMM
    case src
    when OpRegXMM
      rexseq, rexfmt = rex(dst, src)
      modseq, modfmt = modrm(inst, dst, src, dst, src)
      if op0 then
        (rexseq + [op0, 0x0F, op1] + modseq).pack("#{rexfmt}C3#{modfmt}")
      else
        (rexseq + [0x0F, op1] + modseq).pack("#{rexfmt}C2#{modfmt}")
      end

    when OpIndirect
      rexseq, rexfmt = rex(dst, src)
      modseq, modfmt = modrm(inst, dst, src, dst, src)
      if op0 then
        (rexseq + [op0, 0x0F, op1] + modseq).pack("#{rexfmt}C3#{modfmt}")
      else
        (rexseq + [0x0F, op1] + modseq).pack("#{rexfmt}C2#{modfmt}")
      end

    else
      return nosupported_addressing_mode(inst, dst, src)
    end

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

#common_jcc(addr, opc, lopc, inst) ⇒ Object



673
674
675
676
677
678
679
680
681
682
683
684
685
# File 'lib/ytljit/instruction_ia.rb', line 673

def common_jcc(addr, opc, lopc, inst)
  addr2 = addr
  if addr.is_a?(OpMemory) then
    addr2 = addr.value
  end
  offset = addr2 - @asm.current_address - 2
  if offset > -128 and offset < 127 and false then
    [opc, offset].pack("C2")
  else
    offset = addr2 - @asm.current_address - 6
    [0x0F, lopc, offset].pack("C2L")
  end
end

#common_movssd(dst, src, op, inst) ⇒ Object



711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
# File 'lib/ytljit/instruction_ia.rb', line 711

def common_movssd(dst, src, op, inst)
  case dst
  when OpRegXMM
    case src
    when OpRegXMM
      modseq, modfmt = modrm(inst, dst, src, dst, src)
      ([op, 0x0F, 0x10] + modseq).pack("C3#{modfmt}")

    when OpIndirect
      modseq, modfmt = modrm(inst, dst, src, dst, src)
      ([op, 0x0F, 0x10] + modseq).pack("C3#{modfmt}")

    else
      return nosupported_addressing_mode(inst, dst, src)
    end

  when OpIndirect
    case src
    when OpRegXMM
      modseq, modfmt = modrm(inst, src, dst, dst, src)
      ([op, 0x0F, 0x11] + modseq).pack("C3#{modfmt}")
      
    else
      return nosupported_addressing_mode(inst, dst, src)
    end

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

#common_operand_80(dst, src, bopc, optc, inst) ⇒ Object



569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
# File 'lib/ytljit/instruction_ia.rb', line 569

def common_operand_80(dst, src, bopc, optc, inst)
  case dst 
  when OpReg8
    case src
    when OpImmidiate8, Integer
      if dst.class == OpAL then
        [bopc + 0x4, src.value].pack("C2")
      else
        modseq, modfmt = modrm(inst, optc, dst, dst, src)
        ([0x80] + modseq + [src.value]).pack("C#{modfmt}C")
      end
      
    when OpReg8
      modseq, modfmt = modrm(inst, dst, src, dst, src)
      ([bopc] + modseq).pack("C#{modfmt}")

    else
      return nosupported_addressing_mode(inst, dst, src)
    end

  when OpReg32, OpReg64
    case src
    when OpImmidiate8
      common_operand_80_imm8(dst, src.value, optc, inst)

    when OpImmidiate32, Integer
      srcv = nil
      if src.is_a?(Integer)
        srcv = src
      else
        srcv = src.value
      end

      if small_integer_8bit?(srcv) then
        return common_operand_80_imm8(dst, srcv, optc, inst)
      end

      rexseq, rexfmt = rex(dst, src)

      if dst.class == OpEAX or dst.class == OpRAX then
        [*rexseq, bopc + 0x5, srcv].pack("#{rexfmt}CL")
      else
        modseq, modfmt = modrm(inst, optc, dst, dst, src)
        (rexseq + [0x81] + modseq + [srcv]).pack("#{rexfmt}C#{modfmt}L")
      end

    when OpImmidiate64
      srcv = src.value

      if small_integer_8bit?(srcv) then
        return common_operand_80_imm8(dst, srcv, optc, inst)
      end

      rexseq, rexfmt = rex(dst, src)

      if dst.class == OpEAX or dst.class == OpRAX then
        [*rexseq, bopc + 0x5, srcv].pack("#{rexfmt}CQ")
      else
        modseq, modfmt = modrm(inst, optc, dst, dst, src)
        (rexseq + [0x81] + modseq + [srcv]).pack("#{rexfmt}C#{modfmt}Q")
      end

    when OpReg32, OpReg64
      rexseq, rexfmt = rex(dst, src)
      modseq, modfmt = modrm(inst, src, dst, dst, src)
      (rexseq + [bopc + 0x01] + modseq).pack("#{rexfmt}C#{modfmt}")

    when OpMem32, OpMem64
      rexseq, rexfmt = rex(dst, src)
      modseq, modfmt = modrm(inst, src, dst, dst, src)
      (rexseq + [bopc + 0x03] + modseq).pack("#{rexfmt}C#{modfmt}")

    when OpIndirect
      rexseq, rexfmt = rex(src, dst)
      modseq, modfmt = modrm(inst, dst, src, dst, src)
      (rexseq + [bopc + 0x03] + modseq).pack("#{rexfmt}C#{modfmt}")

    else
      return nosupported_addressing_mode(inst, dst, src)
    end

  when OpIndirect
    case src
    when OpImmidiate8
      rexseq, rexfmt = rex(dst, src)
      modseq, modfmt = modrm(inst, optc, src, dst, src)
      (rexseq + [0x83] + modseq + [src.value]).pack("#{rexfmt}C#{modfmt}")

    when OpImmidiate32, Integer
      rexseq, rexfmt = rex(dst, src)
      modseq, modfmt = modrm(inst, optc, src, dst, src)
      (rexseq + [0x81] + modseq + [src.value]).pack("#{rexfmt}C#{modfmt}L")

    when OpReg32, OpReg64
      rexseq, rexfmt = rex(dst, src)
      modseq, modfmt = modrm(inst, src, dst, dst, src)
      (rexseq + [bopc + 0x1] + modseq).pack("#{rexfmt}C#{modfmt}")

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

#common_operand_80_imm8(dst, src, optc, inst) ⇒ Object



562
563
564
565
566
567
# File 'lib/ytljit/instruction_ia.rb', line 562

def common_operand_80_imm8(dst, src, optc, inst)
  rexseq, rexfmt = rex(dst, src)
  modseq, modfmt = modrm(inst, optc, dst, dst, src)
  fmt = "#{rexfmt}C#{modfmt}C"
  (rexseq + [0x83] + modseq + [src]).pack(fmt)
end

#common_setcc(dst, opc, inst) ⇒ Object



687
688
689
690
691
692
693
694
695
# File 'lib/ytljit/instruction_ia.rb', line 687

def common_setcc(dst, opc, inst)
  case dst
  when OpReg8, OpIndirect, OpMem8
    modseq, modfmt = modrm(inst, 0, dst, dst, nil)
    ([0x0F, opc] + modseq).pack("C2#{modfmt}")
  else
    return nosupported_addressing_mode(inst, dst, nil)
  end
end

#common_shift(dst, optc, shftnum, inst) ⇒ Object



697
698
699
700
701
702
703
704
705
706
707
708
709
# File 'lib/ytljit/instruction_ia.rb', line 697

def common_shift(dst, optc, shftnum, inst)
  rexseq, rexfmt = rex(dst, nil)
  modseq, modfmt = modrm(inst, optc, dst, dst, shftnum)
  if shftnum.is_a?(OpImmidiate8) then
    shftnum = shftnum.value
  end

  if shftnum == 1 then
    (rexseq + [0xD1] + modseq ).pack("#{rexfmt}C#{modfmt}")
  else
    (rexseq + [0xC1] + modseq + [shftnum]).pack("#{rexfmt}C#{modfmt}C")
  end
end

#nosupported_addressing_mode(inst, dst, src, src2 = nil) ⇒ Object

Raises:



557
558
559
560
# File 'lib/ytljit/instruction_ia.rb', line 557

def nosupported_addressing_mode(inst, dst, src, src2 = nil)
  mess = "Not supported addessing mode in #{inst} #{dst} #{src} #{src2}"
  raise IlligalOperand, mess
end