<commit_before>#    This file is part of Metasm, the Ruby assembly manipulation suite
#    Copyright (C) 2007 <NAME>
#
#    Licence is LGPL, see LICENCE in the top-level directory


require 'metasm/ia32/main'

module Metasm
class Ia32
	def init_cpu_constants
		@opcode_list ||= []
		@fields_mask.update :w => 1, :s => 1, :d => 1, :modrm => 0xc7,
			:reg => 7, :eeec => 7, :eeed => 7, :seg2 => 3, :seg3 => 7,
			:regfp => 7, :regmmx => 7, :regxmm => 7
		@fields_mask[:seg2A]    = @fields_mask[:seg2]
		@fields_mask[:seg3A]    = @fields_mask[:seg3]
		@fields_mask[:modrmA]   = @fields_mask[:modrm]

		@valid_args.concat [:i, :i8, :u8, :u16, :reg, :seg2, :seg2A,
			:seg3, :seg3A, :eeec, :eeed, :modrm, :modrmA, :mrm_imm,
			:farptr, :imm_val1, :imm_val3, :reg_cl, :reg_eax,
			:reg_dx, :regfp, :regfp0, :modrmmmx, :regmmx,
			:modrmxmm, :regxmm] - @valid_args

		@valid_props.concat [:strop, :stropz, :opsz, :argsz, :setip,
			:stopexec, :saveip, :unsigned_imm, :random, :needpfx,
			:xmmx] - @valid_props
	end

	# only most common instructions from the 386 instruction set
	# inexhaustive list :
	# no aaa, arpl, mov crX, call/jmp/ret far, in/out, bts, xchg...
	def init_386_common_only
		init_cpu_constants

		addop_macro1 'adc', 2
		addop_macro1 'add', 0
		addop_macro1 'and', 4, :u
		addop 'bswap', [0x0F, 0xC8], :reg
		addop 'call',  [0xE8], nil,  {}, :stopexec, :setip, :i, :saveip
		addop 'call',  [0xFF], 2,    {}, :stopexec, :setip, :saveip
		addop('cbw',   [0x98]) { |o| o.props[:opsz] = 16 }
		addop('cdq',   [0x99]) { |o| o.props[:opsz] = 32 }
		addop_macro1 'cmp', 7
		addop_macrostr 'cmps',  [0xA6], :stropz
		addop 'dec',   [0x48], :reg
		addop 'dec',   [0xFE], 1,    {:w => [0, 0]}
		addop 'div',   [0xF6], 6,    {:w => [0, 0]}
		addop 'enter', [0xC8], nil,  {}, :u16, :u8
		addop 'idiv',  [0xF6], 7,    {:w => [0, 0]}
		addop 'imul',  [0xF6], 5,    {:w => [0, 0]}, :reg_eax
		addop 'imul',  [0x0F, 0xAF], :mrm
		addop 'imul',  [0x69], :mrm, {:s => [0, 1]}, :i
		addop 'inc',   [0x40], :reg
		addop 'inc',   [0xFE], 0,    {:w => [0, 0]}
		addop 'int',   [0xCC], nil,  {}, :imm_val3, :stopexec
		addop 'int',   [0xCD], nil,  {}, :u8
		addop_macrotttn 'j', [0x70], nil, {}, :setip, :i8
		addop_macrotttn 'j', [0x0F, 0x80], nil, {}, :setip, :i
		addop 'jmp',   [0xE9], nil,  {:s => [0, 1]}, :setip, :i,  :stopexec
		addop 'jmp',   [0xFF], 4,    {}, :setip, :stopexec
		addop 'lea',   [0x8D], :mrmA
		addop 'leave', [0xC9]
		addop_macrostr 'lods',  [0xAC], :strop
		addop 'loop',  [0xE2], nil,  {}, :setip, :i8
		addop 'loopz', [0xE1], nil,  {}, :setip, :i8
		addop 'loope', [0xE1], nil,  {}, :setip, :i8
		addop 'loopnz',[0xE0], nil,  {}, :setip, :i8
		addop 'loopne',[0xE0], nil,  {}, :setip, :i8
		addop 'mov',   [0xA0], nil,  {:w => [0, 0], :d => [0, 1]}, :mrm_imm, :reg_eax
		addop 'mov',   [0x88], :mrmw,{:d => [0, 1]}
		addop 'mov',   [0xB0], :reg, {:w => [0, 3]}, :u
		addop 'mov',   [0xC6], 0,    {:w => [0, 0]}, :u
		addop_macrostr 'movs',  [0xA4], :strop
		addop 'movsx', [0x0F, 0xBE], :mrmw
		addop 'movzx', [0x0F, 0xB6], :mrmw
		addop 'mul',   [0xF6], 4,    {:w => [0, 0]}
		addop 'neg',   [0xF6], 3,    {:w => [0, 0]}
		addop 'nop',   [0x90]
		addop 'not',   [0xF6], 2,    {:w => [0, 0]}
		addop_macro1 'or', 1, :u
		addop 'pop',   [0x58], :reg
		addop 'pop',   [0x8F], 0
		addop 'push',  [0x50], :reg
		addop 'push',  [0xFF], 6
		addop 'push',  [0x68], nil,  {:s => [0, 1]}, :i
		addop 'ret',   [0xC3], nil,  {}, :stopexec, :setip
		addop 'ret',   [0xC2], nil,  {}, :stopexec, :u16, :setip
		addop_macro3 'rol', 0
		addop_macro3 'ror', 1
		addop_macro3 'sar', 7
		addop_macro1 'sbb', 3
		addop_macrostr 'scas',  [0xAE], :stropz
		addop_macrotttn('set', [0x0F, 0x90], 0) { |o| o.props[:argsz] = 8 }
		addop_macrotttn('set', [0x0F, 0x90], :mrm) { |o| o.props[:argsz] = 8 ; o.args.reverse! }	# :reg field is unused
		addop_macro3 'shl', 4
		addop_macro3 'sal', 4
		addop 'shld',  [0x0F, 0xA4], :mrm, {}, :u8
		addop 'shld',  [0x0F, 0xA5], :mrm, {}, :reg_cl
		addop_macro3 'shr', 5
		addop 'shrd',  [0x0F, 0xAC], :mrm, {}, :u8
		addop 'shrd',  [0x0F, 0xAD], :mrm, {}, :reg_cl
		addop_macrostr 'stos',  [0xAA], :strop
		addop_macro1 'sub', 5
		addop 'test',  [0x84], :mrmw
		addop 'test',  [0xA8], nil,  {:w => [0, 0]}, :reg_eax, :u
		addop 'test',  [0xF6], 0,    {:w => [0, 0]}, :u
		addop_macro1 'xor', 6, :u
	end

	def init_386_only
		init_cpu_constants

		addop 'aaa',   [0x37]
		addop 'aad',   [0xD5, 0x0A]
		addop 'aam',   [0xD4, 0x0A]
		addop 'aas',   [0x3F]
		addop 'arpl',  [0x63], :mrm
		addop 'bound', [0x62], :mrmA
		addop 'bsf',   [0x0F, 0xBC], :mrm
		addop 'bsr',   [0x0F, 0xBD], :mrm
		addop_macro2 'bt' , 0
		addop_macro2 'btc', 3
		addop_macro2 'btr', 2
		addop_macro2 'bts', 1
		addop 'call',  [0x9A], nil,  {}, :stopexec, :setip, :farptr, :saveip
		addop 'callf', [0xFF], 3,    {}, :stopexec, :setip, :saveip
		addop 'clc',   [0xF8]
		addop 'cld',   [0xFC]
		addop 'cli',   [0xFA]
		addop 'clts',  [0x0F, 0x06]
		addop 'cmc',   [0xF5]
		addop('cmpxchg',[0x0F, 0xB0], :mrmw) { |o| o.args.reverse! }
		addop 'cpuid', [0x0F, 0xA2]
		addop('cwd',   [0x99]) { |o| o.props[:opsz] = 16 }
		addop('cwde',  [0x98]) { |o| o.props[:opsz] = 32 }
		addop 'daa',   [0x27]
		addop 'das',   [0x2F]
		addop 'hlt',   [0xF4], nil, {}, :stopexec
		addop 'in',    [0xE4], nil,  {:w => [0, 0]}, :reg_eax, :u8
		addop 'in',    [0xE4], nil,  {:w => [0, 0]}, :u8
		addop 'in',    [0xEC], nil,  {:w => [0, 0]}, :reg_eax, :reg_dx
		addop 'in',    [0xEC], nil,  {:w => [0, 0]}, :reg_eax
		addop 'in',    [0xEC], nil,  {:w => [0, 0]}
		addop_macrostr 'ins',   [0x6C], :strop
		addop 'into',  [0xCE]
		addop 'invd',  [0x0F, 0x08]
		addop 'invlpg',[0x0F, 0x01, 7<<3], :modrmA
		addop('movd',  [0x0F, 0x6E], :mrmmmx, {:d => [1, 4]}) { |o| o.args[o.args.index(:modrmmmx)] = :modrm }
		addop 'iret',  [0xCF], nil,  {}, :stopexec, :setip
		addop 'iretd', [0xCF], nil,  {}, :stopexec, :setip
		addop('jcxz',  [0xE3], nil,  {}, :setip, :i8) { |o| o.props[:opsz] = 16 }
		addop('jecxz', [0xE3], nil,  {}, :setip, :i8) { |o| o.props[:opsz] = 32 }
		addop 'jmp',   [0xEA], nil,  {}, :farptr, :stopexec
		addop 'jmpf',  [0xFF], 5,    {}, :stopexec		# reg ?
		addop 'lahf',  [0x9F]
		addop 'lar',   [0x0F, 0x02], :mrm
		addop 'lds',   [0xC5], :mrmA<commit_msg>ia32: refix movd<commit_after>#    This file is part of Metasm, the Ruby assembly manipulation suite
#    Copyright (C) 2007 <NAME>
#
#    Licence is LGPL, see LICENCE in the top-level directory


require 'metasm/ia32/main'

module Metasm
class Ia32
	def init_cpu_constants
		@opcode_list ||= []
		@fields_mask.update :w => 1, :s => 1, :d => 1, :modrm => 0xc7,
			:reg => 7, :eeec => 7, :eeed => 7, :seg2 => 3, :seg3 => 7,
			:regfp => 7, :regmmx => 7, :regxmm => 7
		@fields_mask[:seg2A]    = @fields_mask[:seg2]
		@fields_mask[:seg3A]    = @fields_mask[:seg3]
		@fields_mask[:modrmA]   = @fields_mask[:modrm]

		@valid_args.concat [:i, :i8, :u8, :u16, :reg, :seg2, :seg2A,
			:seg3, :seg3A, :eeec, :eeed, :modrm, :modrmA, :mrm_imm,
			:farptr, :imm_val1, :imm_val3, :reg_cl, :reg_eax,
			:reg_dx, :regfp, :regfp0, :modrmmmx, :regmmx,
			:modrmxmm, :regxmm] - @valid_args

		@valid_props.concat [:strop, :stropz, :opsz, :argsz, :setip,
			:stopexec, :saveip, :unsigned_imm, :random, :needpfx,
			:xmmx] - @valid_props
	end

	# only most common instructions from the 386 instruction set
	# inexhaustive list :
	# no aaa, arpl, mov crX, call/jmp/ret far, in/out, bts, xchg...
	def init_386_common_only
		init_cpu_constants

		addop_macro1 'adc', 2
		addop_macro1 'add', 0
		addop_macro1 'and', 4, :u
		addop 'bswap', [0x0F, 0xC8], :reg
		addop 'call',  [0xE8], nil,  {}, :stopexec, :setip, :i, :saveip
		addop 'call',  [0xFF], 2,    {}, :stopexec, :setip, :saveip
		addop('cbw',   [0x98]) { |o| o.props[:opsz] = 16 }
		addop('cdq',   [0x99]) { |o| o.props[:opsz] = 32 }
		addop_macro1 'cmp', 7
		addop_macrostr 'cmps',  [0xA6], :stropz
		addop 'dec',   [0x48], :reg
		addop 'dec',   [0xFE], 1,    {:w => [0, 0]}
		addop 'div',   [0xF6], 6,    {:w => [0, 0]}
		addop 'enter', [0xC8], nil,  {}, :u16, :u8
		addop 'idiv',  [0xF6], 7,    {:w => [0, 0]}
		addop 'imul',  [0xF6], 5,    {:w => [0, 0]}, :reg_eax
		addop 'imul',  [0x0F, 0xAF], :mrm
		addop 'imul',  [0x69], :mrm, {:s => [0, 1]}, :i
		addop 'inc',   [0x40], :reg
		addop 'inc',   [0xFE], 0,    {:w => [0, 0]}
		addop 'int',   [0xCC], nil,  {}, :imm_val3, :stopexec
		addop 'int',   [0xCD], nil,  {}, :u8
		addop_macrotttn 'j', [0x70], nil, {}, :setip, :i8
		addop_macrotttn 'j', [0x0F, 0x80], nil, {}, :setip, :i
		addop 'jmp',   [0xE9], nil,  {:s => [0, 1]}, :setip, :i,  :stopexec
		addop 'jmp',   [0xFF], 4,    {}, :setip, :stopexec
		addop 'lea',   [0x8D], :mrmA
		addop 'leave', [0xC9]
		addop_macrostr 'lods',  [0xAC], :strop
		addop 'loop',  [0xE2], nil,  {}, :setip, :i8
		addop 'loopz', [0xE1], nil,  {}, :setip, :i8
		addop 'loope', [0xE1], nil,  {}, :setip, :i8
		addop 'loopnz',[0xE0], nil,  {}, :setip, :i8
		addop 'loopne',[0xE0], nil,  {}, :setip, :i8
		addop 'mov',   [0xA0], nil,  {:w => [0, 0], :d => [0, 1]}, :mrm_imm, :reg_eax
		addop 'mov',   [0x88], :mrmw,{:d => [0, 1]}
		addop 'mov',   [0xB0], :reg, {:w => [0, 3]}, :u
		addop 'mov',   [0xC6], 0,    {:w => [0, 0]}, :u
		addop_macrostr 'movs',  [0xA4], :strop
		addop 'movsx', [0x0F, 0xBE], :mrmw
		addop 'movzx', [0x0F, 0xB6], :mrmw
		addop 'mul',   [0xF6], 4,    {:w => [0, 0]}
		addop 'neg',   [0xF6], 3,    {:w => [0, 0]}
		addop 'nop',   [0x90]
		addop 'not',   [0xF6], 2,    {:w => [0, 0]}
		addop_macro1 'or', 1, :u
		addop 'pop',   [0x58], :reg
		addop 'pop',   [0x8F], 0
		addop 'push',  [0x50], :reg
		addop 'push',  [0xFF], 6
		addop 'push',  [0x68], nil,  {:s => [0, 1]}, :i
		addop 'ret',   [0xC3], nil,  {}, :stopexec, :setip
		addop 'ret',   [0xC2], nil,  {}, :stopexec, :u16, :setip
		addop_macro3 'rol', 0
		addop_macro3 'ror', 1
		addop_macro3 'sar', 7
		addop_macro1 'sbb', 3
		addop_macrostr 'scas',  [0xAE], :stropz
		addop_macrotttn('set', [0x0F, 0x90], 0) { |o| o.props[:argsz] = 8 }
		addop_macrotttn('set', [0x0F, 0x90], :mrm) { |o| o.props[:argsz] = 8 ; o.args.reverse! }	# :reg field is unused
		addop_macro3 'shl', 4
		addop_macro3 'sal', 4
		addop 'shld',  [0x0F, 0xA4], :mrm, {}, :u8
		addop 'shld',  [0x0F, 0xA5], :mrm, {}, :reg_cl
		addop_macro3 'shr', 5
		addop 'shrd',  [0x0F, 0xAC], :mrm, {}, :u8
		addop 'shrd',  [0x0F, 0xAD], :mrm, {}, :reg_cl
		addop_macrostr 'stos',  [0xAA], :strop
		addop_macro1 'sub', 5
		addop 'test',  [0x84], :mrmw
		addop 'test',  [0xA8], nil,  {:w => [0, 0]}, :reg_eax, :u
		addop 'test',  [0xF6], 0,    {:w => [0, 0]}, :u
		addop_macro1 'xor', 6, :u
	end

	def init_386_only
		init_cpu_constants

		addop 'aaa',   [0x37]
		addop 'aad',   [0xD5, 0x0A]
		addop 'aam',   [0xD4, 0x0A]
		addop 'aas',   [0x3F]
		addop 'arpl',  [0x63], :mrm
		addop 'bound', [0x62], :mrmA
		addop 'bsf',   [0x0F, 0xBC], :mrm
		addop 'bsr',   [0x0F, 0xBD], :mrm
		addop_macro2 'bt' , 0
		addop_macro2 'btc', 3
		addop_macro2 'btr', 2
		addop_macro2 'bts', 1
		addop 'call',  [0x9A], nil,  {}, :stopexec, :setip, :farptr, :saveip
		addop 'callf', [0xFF], 3,    {}, :stopexec, :setip, :saveip
		addop 'clc',   [0xF8]
		addop 'cld',   [0xFC]
		addop 'cli',   [0xFA]
		addop 'clts',  [0x0F, 0x06]
		addop 'cmc',   [0xF5]
		addop('cmpxchg',[0x0F, 0xB0], :mrmw) { |o| o.args.reverse! }
		addop 'cpuid', [0x0F, 0xA2]
		addop('cwd',   [0x99]) { |o| o.props[:opsz] = 16 }
		addop('cwde',  [0x98]) { |o| o.props[:opsz] = 32 }
		addop 'daa',   [0x27]
		addop 'das',   [0x2F]
		addop 'hlt',   [0xF4], nil, {}, :stopexec
		addop 'in',    [0xE4], nil,  {:w => [0, 0]}, :reg_eax, :u8
		addop 'in',    [0xE4], nil,  {:w => [0, 0]}, :u8
		addop 'in',    [0xEC], nil,  {:w => [0, 0]}, :reg_eax, :reg_dx
		addop 'in',    [0xEC], nil,  {:w => [0, 0]}, :reg_eax
		addop 'in',    [0xEC], nil,  {:w => [0, 0]}
		addop_macrostr 'ins',   [0x6C], :strop
		addop 'into',  [0xCE]
		addop 'invd',  [0x0F, 0x08]
		addop 'invlpg',[0x0F, 0x01, 7<<3], :modrmA
		addop('movd',  [0x0F, 0x6E], :mrmmmx, {:d => [1, 4]}) { |o| o.args[o.args.index(:modrmmmx)] = :modrm ; o.args.reverse! }
		addop 'iret',  [0xCF], nil,  {}, :stopexec, :setip
		addop 'iretd', [0xCF], nil,  {}, :stopexec, :setip
		addop('jcxz',  [0xE3], nil,  {}, :setip, :i8) { |o| o.props[:opsz] = 16 }
		addop('jecxz', [0xE3], nil,  {}, :setip, :i8) { |o| o.props[:opsz] = 32 }
		addop 'jmp',   [0xEA], nil,  {}, :farptr, :stopexec
		addop 'jmpf',  [0xFF], 5,    {}, :stopexec		# reg ?
		addop 'lahf',  [0x9F]
		addop 'lar',   [0x0F, 0x02], :mrm
		addop 'lds',   [0xC5], :mrmA
{'fraction_non_alphanumeric': 0.23430394894295972, 'fraction_numerical': 0.06796968488232948, 'mean_word_length': 3.4187522030313713, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1269407', 'n_tokens_mistral': 7109, 'n_tokens_neox': 6423, 'n_words': 1524}