if ~ defined MPX restore MPX ; this ensures that symbol cannot be forward-referenced MPX = 1 element MPX.bnd repeat 4, i:0 element bnd#i? : MPX.bnd + i end repeat macro MPX.parse_operand ns,op x86.parse_operand#ns op if ns.type = 'imm' & ns.size = 0 & ns.imm eq 1 elementof ns.imm & 1 metadataof ns.imm relativeto MPX.bnd ns.type = 'bnd' ns.mod = 11b ns.rm = 1 metadataof ns.imm - MPX.bnd ns.size = 0 end if end macro macro MPX.parse_sib_operand ns,op& match [b=,si], op ns.split = 1 ns.segment_prefix = 0 ns.prefix = 0 ns.opcode_prefix = 0 ns.rex_prefix = 0 ns.size = 0 ns.type = 'mem' ns.base_part = +b ns.index_part = +si if x86.mode = 64 ns.mode = 64 ns.address_registers_type = x86.r64 else ns.mode = 32 ns.address_registers_type = x86.r32 end if ns.base_registers = 0 ns.index_registers = 0 repeat elementsof ns.base_part if % metadataof ns.base_part relativeto x86.r16 | % metadataof ns.base_part relativeto x86.r32 | % metadataof ns.base_part relativeto x86.r64 | % metadataof ns.address relativeto x86.ip ns.base_registers = ns.base_registers + % elementof ns.base_part * % scaleof ns.base_part end if end repeat repeat elementsof ns.index_part if % metadataof ns.index_part relativeto x86.r16 | % metadataof ns.index_part relativeto x86.r32 | % metadataof ns.index_part relativeto x86.r64 | % metadataof ns.address relativeto x86.ip ns.index_registers = ns.index_registers + % elementof ns.index_part * % scaleof ns.index_part end if end repeat ns.displacement = ns.base_part - ns.base_registers + ns.index_part - ns.index_registers if ns.index_registers eq 0 ns.index = 4 ns.scale = 1 else if elementsof ns.index_registers = 1 & 1 metadataof ns.index_registers relativeto ns.address_registers_type & 1 metadataof ns.index_registers - ns.address_registers_type <> 4 ns.index = 1 metadataof ns.index_registers - ns.address_registers_type ns.scale = 1 scaleof ns.index_registers else err 'invalid address' end if if ns.base_registers eq 0 ns.rm = 4 ns.base = 5 ns.index_only = 1 else if ns.base_registers eq 1 elementof ns.base_registers & 1 metadataof ns.base_registers relativeto ns.address_registers_type ns.base = 1 metadataof ns.base_registers - ns.address_registers_type if ns.index = 4 & ns.base <> 4 ns.rm = ns.base else ns.rm = 4 end if ns.index_only = 0 else err 'invalid address' end if ns.auto_relative = 0 ns.displacement_size = 4 ns.mod = 2 if ns.index_only ns.mod = 0 else if ns.displacement relativeto 0 if ns.displacement = 0 & ns.rm and 111b <> 5 & (ns.rm <> 4 | ns.base and 111b <> 5) ns.displacement_size = 0 ns.mod = 0 else if ns.displacement < 80h & ns.displacement >= -80h ns.displacement_size = 1 ns.mod = 1 else if ns.displacement - 1 shl ns.mode >= -80h & ns.displacement < 1 shl ns.mode ns.displacement = ns.displacement - 1 shl ns.mode ns.displacement_size = 1 ns.mod = 1 end if end if else ns.split = 0 x86.parse_operand#ns op end match end macro macro bndmk? dest*,src*& MPX.parse_operand @dest,dest MPX.parse_sib_operand @src,src if @dest.type = 'bnd' & @src.type = 'mem' if @src.split & ~ 0 scaleof @src.base_part eq 0 err 'invalid base address' end if if (x86.mode = 64 & @src.size and not 8) | (x86.mode < 64 & @src.size and not 4) err 'invalid operand size' end if @src.opcode_prefix = 0F3h x86.store_instruction@src <0Fh,1Bh>,@dest.rm else err 'invalid combination of operands' end if end macro macro bndmov? dest*,src* MPX.parse_operand @dest,dest MPX.parse_operand @src,src if @dest.type = 'bnd' & (@src.type = 'bnd' | @src.type = 'mem') if (x86.mode = 64 & @src.size and not 16) | (x86.mode < 64 & @src.size and not 8) err 'invalid operand size' end if if @src.type = 'mem' & @src.mode <> x86.mode err 'invalid address' end if @src.opcode_prefix = 66h x86.store_instruction@src <0Fh,1Ah>,@dest.rm else if @dest.type = 'mem' & @src.type = 'bnd' if (x86.mode = 64 & @dest.size and not 16) | (x86.mode < 64 & @dest.size and not 8) err 'invalid operand size' end if if @dest.type = 'mem' & @dest.mode <> x86.mode err 'invalid address' end if @dest.opcode_prefix = 66h x86.store_instruction@dest <0Fh,1Bh>,@src.rm else err 'invalid combination of operands' end if end macro iterate , bndcl,0F3h,1Ah, bndcu,0F2h,1Ah, bndcn,0F2h,1Bh macro instr? dest*,src* MPX.parse_operand @dest,dest x86.parse_operand @src,src if @dest.type = 'bnd' & (@src.type = 'reg' | @src.type = 'mem') if (x86.mode = 64 & @src.size and not 8) | (x86.mode < 64 & @src.size and not 4) err 'invalid operand size' end if if @src.type = 'mem' & @src.mode <> x86.mode err 'invalid address' end if @src.opcode_prefix = prefix x86.store_instruction@src <0Fh,ext>,@dest.rm else err 'invalid operand' end if end macro end iterate macro bndldx? dest*,src*& MPX.parse_operand @dest,dest MPX.parse_sib_operand @src,src if @dest.type = 'bnd' & @src.type = 'mem' if @src.scale > 1 | ( @src.split & ~ 0 scaleof @src.index_part eq 0 ) err 'invalid index' end if x86.store_instruction@src <0Fh,1Ah>,@dest.rm else err 'invalid combination of operands' end if end macro macro bndstx? operands*& match [dest] =, src, operands MPX.parse_sib_operand @dest,[dest] MPX.parse_operand @src,src if @dest.type = 'mem' & @src.type = 'bnd' if @dest.scale > 1 | ( @dest.split & ~ 0 scaleof @dest.index_part eq 0 ) err 'invalid index' end if x86.store_instruction@dest <0Fh,1Bh>,@src.rm else err 'invalid combination of operands' end if else err 'invalid combination of operands' end match end macro end if