]>
git.saurik.com Git - apple/javascriptcore.git/blob - offlineasm/x86.rb
1 # Copyright (C) 2012 Apple Inc. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
6 # 1. Redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer.
8 # 2. Redistributions in binary form must reproduce the above copyright
9 # notice, this list of conditions and the following disclaimer in the
10 # documentation and/or other materials provided with the distribution.
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22 # THE POSSIBILITY OF SUCH DAMAGE.
31 raise "bad value for $activeBackend: #{$activeBackend}"
35 class SpecialRegister
< NoChildren
37 raise unless @name =~
/^r/
50 def x86CallOperand(kind
)
51 "*#{x86Operand(kind)}"
55 X64_SCRATCH_REGISTER
= SpecialRegister
.new("r11")
60 when "t0", "a0", "r0", "t1", "a1", "r1", "t2", "t3"
62 when "cfr", "ttnr", "tmr"
82 isX64
? "%rax" : "%eax"
95 isX64
? "%rdx" : "%edx"
108 isX64
? "%rcx" : "%ecx"
121 isX64
? "%rbx" : "%ebx"
134 isX64
? "%rsi" : "%esi"
173 isX64
? "%rsp" : "%esp"
178 raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
190 raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
200 raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
210 raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
220 raise "Bad register #{name} for X86 at #{codeOriginString}"
223 def x86CallOperand(kind
)
224 "*#{x86Operand(kind)}"
230 raise unless kind
== :double
232 when "ft0", "fa0", "fr"
245 raise "Bad register #{name} for X86 at #{codeOriginString}"
248 def x86CallOperand(kind
)
249 "*#{x86Operand(kind)}"
254 def validX86Immediate
?
256 value
>= -0x80000000 and value
<= 0x7fffffff
264 def x86CallOperand(kind
)
270 def supports8BitOnX86
274 def x86AddressOperand(addressKind
)
275 "#{offset.value}(#{base.x86Operand(addressKind)})"
278 x86AddressOperand(:ptr)
280 def x86CallOperand(kind
)
281 "*#{x86Operand(kind)}"
286 def supports8BitOnX86
290 def x86AddressOperand(addressKind
)
291 "#{offset.value}(#{base.x86Operand(addressKind)}, #{index.x86Operand(addressKind)}, #{scale})"
295 x86AddressOperand(:ptr)
298 def x86CallOperand(kind
)
299 "*#{x86Operand(kind)}"
303 class AbsoluteAddress
304 def supports8BitOnX86
308 def x86AddressOperand(addressKind
)
316 def x86CallOperand(kind
)
322 def x86CallOperand(kind
)
327 class LocalLabelReference
328 def x86CallOperand(kind
)
334 def getModifiedListX86_64
340 if node
.is_a
? Instruction
341 unless node
.opcode
== "move"
343 newOperands
= node
.operands
.map
{
345 if operand
.immediate
? and not operand
.validX86Immediate
?
347 raise "Attempt to use scratch register twice at #{operand.codeOriginString}"
349 newList
<< Instruction
.new(operand
.codeOrigin
, "move", [operand
, X64_SCRATCH_REGISTER
])
356 newNode
= Instruction
.new(node
.codeOrigin
, node
.opcode
, newOperands
)
359 unless node
.is_a
? Label
or
360 node
.is_a
? LocalLabel
or
362 raise "Unexpected #{node.inspect} at #{node.codeOrigin}"
375 def x86Operands(*kinds
)
376 raise unless kinds
.size
== operands
.size
380 result
<< operands
[idx
].x86Operand(kinds
[idx
])
419 def handleX86OpWithNumOperands(opcode
, kind
, numOperands
)
421 if operands
[0] == operands
[2]
422 $asm.puts
"#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
423 elsif operands
[1] == operands
[2]
424 $asm.puts
"#{opcode} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
426 $asm.puts
"mov#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
427 $asm.puts
"#{opcode} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
430 $asm.puts
"#{opcode} #{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}"
434 def handleX86Op(opcode
, kind
)
435 handleX86OpWithNumOperands(opcode
, kind
, operands
.size
)
438 def handleX86Shift(opcode
, kind
)
439 if operands
[0].is_a
? Immediate
or operands
[0] == RegisterID
.forName(nil, "t2")
440 $asm.puts
"#{opcode} #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(kind)}"
442 cx
= RegisterID
.forName(nil, "t2")
443 $asm.puts
"xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{cx.x86Operand(:ptr)}"
444 $asm.puts
"#{opcode} %cl, #{operands[1].x86Operand(kind)}"
445 $asm.puts
"xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{cx.x86Operand(:ptr)}"
449 def handleX86DoubleBranch(branchOpcode
, mode
)
452 $asm.puts
"ucomisd #{operands[1].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
454 $asm.puts
"ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
458 $asm.puts
"#{branchOpcode} #{operands[2].asmLabel}"
461 def handleX86IntCompare(opcodeSuffix
, kind
)
462 if operands
[0].is_a
? Immediate
and operands
[0].value
== 0 and operands
[1].is_a
? RegisterID
and (opcodeSuffix
== "e" or opcodeSuffix
== "ne")
463 $asm.puts
"test#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}"
464 elsif operands
[1].is_a
? Immediate
and operands
[1].value
== 0 and operands
[0].is_a
? RegisterID
and (opcodeSuffix
== "e" or opcodeSuffix
== "ne")
465 $asm.puts
"test#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}"
467 $asm.puts
"cmp#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[0].x86Operand(kind)}"
471 def handleX86IntBranch(branchOpcode
, kind
)
472 handleX86IntCompare(branchOpcode
[1..-1], kind
)
473 $asm.puts
"#{branchOpcode} #{operands[2].asmLabel}"
476 def handleX86Set(setOpcode
, operand
)
477 if operand
.supports8BitOnX86
478 $asm.puts
"#{setOpcode} #{operand.x86Operand(:byte)}"
479 $asm.puts
"movzbl #{operand.x86Operand(:byte)}, #{operand.x86Operand(:int)}"
481 ax
= RegisterID
.new(nil, "t0")
482 $asm.puts
"xchg#{x86Suffix(:ptr)} #{operand.x86Operand(:ptr)}, #{ax.x86Operand(:ptr)}"
483 $asm.puts
"#{setOpcode} %al"
484 $asm.puts
"movzbl %al, %eax"
485 $asm.puts
"xchg#{x86Suffix(:ptr)} #{operand.x86Operand(:ptr)}, #{ax.x86Operand(:ptr)}"
489 def handleX86IntCompareSet(setOpcode
, kind
)
490 handleX86IntCompare(setOpcode
[3..-1], kind
)
491 handleX86Set(setOpcode
, operands
[2])
494 def handleX86Test(kind
)
498 mask
= Immediate
.new(codeOrigin
, -1)
502 raise "Expected 2 or 3 operands, but got #{operands.size} at #{codeOriginString}"
505 if mask
.is_a
? Immediate
and mask
.value
== -1
506 if value
.is_a
? RegisterID
507 $asm.puts
"test#{x86Suffix(kind)} #{value.x86Operand(kind)}, #{value.x86Operand(kind)}"
509 $asm.puts
"cmp#{x86Suffix(kind)} $0, #{value.x86Operand(kind)}"
512 $asm.puts
"test#{x86Suffix(kind)} #{mask.x86Operand(kind)}, #{value.x86Operand(kind)}"
516 def handleX86BranchTest(branchOpcode
, kind
)
518 $asm.puts
"#{branchOpcode} #{operands.last.asmLabel}"
521 def handleX86SetTest(setOpcode
, kind
)
523 handleX86Set(setOpcode
, operands
.last
)
526 def handleX86OpBranch(opcode
, branchOpcode
, kind
)
527 handleX86OpWithNumOperands(opcode
, kind
, operands
.size
- 1)
530 jumpTarget
= operands
[3]
532 jumpTarget
= operands
[2]
536 $asm.puts
"#{branchOpcode} #{jumpTarget.asmLabel}"
539 def handleX86SubBranch(branchOpcode
, kind
)
540 if operands
.size
== 4 and operands
[1] == operands
[2]
541 $asm.puts
"neg#{x86Suffix(kind)} #{operands[2].x86Operand(kind)}"
542 $asm.puts
"add#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
544 handleX86OpWithNumOperands("sub#{x86Suffix(kind)}", kind
, operands
.size
- 1)
548 jumpTarget
= operands
[3]
550 jumpTarget
= operands
[2]
554 $asm.puts
"#{branchOpcode} #{jumpTarget.asmLabel}"
557 def handleX86Add(kind
)
558 if operands
.size
== 3 and operands
[0].is_a
? Immediate
559 raise unless operands
[1].is_a
? RegisterID
560 raise unless operands
[2].is_a
? RegisterID
561 if operands
[0].value
== 0
562 unless operands
[1] == operands
[2]
563 $asm.puts
"mov#{x86Suffix(kind)} #{operands[1].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
566 $asm.puts
"lea#{x86Suffix(kind)} #{operands[0].value}(#{operands[1].x86Operand(kind)}), #{operands[2].x86Operand(kind)}"
568 elsif operands
.size
== 3 and operands
[0].is_a
? RegisterID
569 raise unless operands
[1].is_a
? RegisterID
570 raise unless operands
[2].is_a
? RegisterID
571 $asm.puts
"lea#{x86Suffix(kind)} (#{operands[0].x86Operand(kind)}, #{operands[1].x86Operand(kind)}), #{operands[2].x86Operand(kind)}"
573 unless Immediate
.new(nil, 0) == operands
[0]
574 $asm.puts
"add#{x86Suffix(kind)} #{x86Operands(kind, kind)}"
579 def handleX86Sub(kind
)
580 if operands
.size
== 3 and operands
[1] == operands
[2]
581 $asm.puts
"neg#{x86Suffix(kind)} #{operands[2].x86Operand(kind)}"
582 $asm.puts
"add#{x86Suffix(kind)} #{operands[0].x86Operand(kind)}, #{operands[2].x86Operand(kind)}"
584 handleX86Op("sub#{x86Suffix(kind)}", kind
)
588 def handleX86Mul(kind
)
589 if operands
.size
== 3 and operands
[0].is_a
? Immediate
590 $asm.puts
"imul#{x86Suffix(kind)} #{x86Operands(kind, kind, kind)}"
592 # FIXME: could do some peephole in case the left operand is immediate and it's
594 handleX86Op("imul#{x86Suffix(kind)}", kind
)
599 if Immediate
.new(nil, 0) == operands
[0] and operands
[1].is_a
? RegisterID
600 $asm.puts
"xor#{x86Suffix(:ptr)} #{operands[1].x86Operand(:ptr)}, #{operands[1].x86Operand(:ptr)}"
601 elsif operands
[0] !
= operands
[1]
602 $asm.puts
"mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}"
607 raise unless $activeBackend == "X86"
612 raise unless $activeBackend == "X86_64"
617 $asm.comment codeOriginString
624 handleX86Op("andl", :int)
626 handleX86Op("and#{x86Suffix(:ptr)}", :ptr)
628 handleX86Shift("sall", :int)
630 handleX86Shift("sal#{x86Suffix(:ptr)}", :ptr)
636 $asm.puts
"negl #{x86Operands(:int)}"
638 $asm.puts
"neg#{x86Suffix(:ptr)} #{x86Operands(:ptr)}"
640 $asm.puts
"notl #{x86Operands(:int)}"
642 handleX86Op("orl", :int)
644 handleX86Op("or#{x86Suffix(:ptr)}", :ptr)
646 handleX86Shift("sarl", :int)
648 handleX86Shift("sar#{x86Suffix(:ptr)}", :ptr)
650 handleX86Shift("shrl", :int)
652 handleX86Shift("shr#{x86Suffix(:ptr)}", :ptr)
658 handleX86Op("xorl", :int)
660 handleX86Op("xor#{x86Suffix(:ptr)}", :ptr)
661 when "loadi", "storei"
662 $asm.puts
"movl #{x86Operands(:int, :int)}"
665 $asm.puts
"movslq #{x86Operands(:int, :ptr)}"
667 $asm.puts
"movl #{x86Operands(:int, :int)}"
669 when "loadp", "storep"
670 $asm.puts
"mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}"
672 $asm.puts
"movzbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
674 $asm.puts
"movsbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
676 $asm.puts
"movzwl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
678 $asm.puts
"movswl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
680 $asm.puts
"movb #{x86Operands(:byte, :byte)}"
681 when "loadd", "moved", "stored"
682 $asm.puts
"movsd #{x86Operands(:double, :double)}"
684 $asm.puts
"addsd #{x86Operands(:double, :double)}"
686 $asm.puts
"divsd #{x86Operands(:double, :double)}"
688 $asm.puts
"subsd #{x86Operands(:double, :double)}"
690 $asm.puts
"mulsd #{x86Operands(:double, :double)}"
692 $asm.puts
"sqrtsd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
694 $asm.puts
"cvtsi2sd #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:double)}"
696 isUnordered
= LocalLabel
.unique("bdeq")
697 $asm.puts
"ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
698 $asm.puts
"jp #{LabelReference.new(codeOrigin, isUnordered).asmLabel}"
699 $asm.puts
"je #{LabelReference.new(codeOrigin, operands[2]).asmLabel}"
700 isUnordered
.lower("X86")
702 handleX86DoubleBranch("jne", :normal)
704 handleX86DoubleBranch("ja", :normal)
706 handleX86DoubleBranch("jae", :normal)
708 handleX86DoubleBranch("ja", :reverse)
710 handleX86DoubleBranch("jae", :reverse)
712 handleX86DoubleBranch("je", :normal)
714 isUnordered
= LocalLabel
.unique("bdnequn")
715 isEqual
= LocalLabel
.unique("bdnequn")
716 $asm.puts
"ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
717 $asm.puts
"jp #{LabelReference.new(codeOrigin, isUnordered).asmLabel}"
718 $asm.puts
"je #{LabelReference.new(codeOrigin, isEqual).asmLabel}"
719 isUnordered
.lower("X86")
720 $asm.puts
"jmp #{operands[2].asmLabel}"
723 handleX86DoubleBranch("jb", :reverse)
725 handleX86DoubleBranch("jbe", :reverse)
727 handleX86DoubleBranch("jb", :normal)
729 handleX86DoubleBranch("jbe", :normal)
731 $asm.puts
"cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
732 $asm.puts
"cmpl $0x80000000 #{operands[1].x86Operand(:int)}"
733 $asm.puts
"je #{operands[2].asmLabel}"
735 $asm.puts
"cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
737 $asm.puts
"cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
738 $asm.puts
"testl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
739 $asm.puts
"je #{operands[2].asmLabel}"
740 $asm.puts
"cvtsi2sd #{operands[1].x86Operand(:int)}, %xmm7"
741 $asm.puts
"ucomisd #{operands[0].x86Operand(:double)}, %xmm7"
742 $asm.puts
"jp #{operands[2].asmLabel}"
743 $asm.puts
"jne #{operands[2].asmLabel}"
745 $asm.puts
"xorpd #{operands[0].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
747 $asm.puts
"pop #{operands[0].x86Operand(:ptr)}"
749 $asm.puts
"push #{operands[0].x86Operand(:ptr)}"
754 $asm.puts
"movslq #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:ptr)}"
760 $asm.puts
"movl #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
767 handleX86IntBranch("je", :int)
769 handleX86IntBranch("je", :ptr)
771 handleX86IntBranch("jne", :int)
773 handleX86IntBranch("jne", :ptr)
775 handleX86IntBranch("ja", :int)
777 handleX86IntBranch("ja", :ptr)
779 handleX86IntBranch("jae", :int)
781 handleX86IntBranch("jae", :ptr)
783 handleX86IntBranch("jb", :int)
785 handleX86IntBranch("jb", :ptr)
787 handleX86IntBranch("jbe", :int)
789 handleX86IntBranch("jbe", :ptr)
791 handleX86IntBranch("jg", :int)
793 handleX86IntBranch("jg", :ptr)
795 handleX86IntBranch("jge", :int)
797 handleX86IntBranch("jge", :ptr)
799 handleX86IntBranch("jl", :int)
801 handleX86IntBranch("jl", :ptr)
803 handleX86IntBranch("jle", :int)
805 handleX86IntBranch("jle", :ptr)
807 handleX86IntBranch("je", :byte)
809 handleX86IntBranch("jne", :byte)
811 handleX86IntBranch("ja", :byte)
813 handleX86IntBranch("jae", :byte)
815 handleX86IntBranch("jb", :byte)
817 handleX86IntBranch("jbe", :byte)
819 handleX86IntBranch("jg", :byte)
821 handleX86IntBranch("jge", :byte)
823 handleX86IntBranch("jl", :byte)
825 handleX86IntBranch("jlteq", :byte)
827 handleX86BranchTest("jo", :int)
829 handleX86BranchTest("jo", :ptr)
831 handleX86BranchTest("js", :int)
833 handleX86BranchTest("js", :ptr)
835 handleX86BranchTest("jz", :int)
837 handleX86BranchTest("jz", :ptr)
839 handleX86BranchTest("jnz", :int)
841 handleX86BranchTest("jnz", :ptr)
843 handleX86BranchTest("jo", :byte)
845 handleX86BranchTest("js", :byte)
847 handleX86BranchTest("jz", :byte)
849 handleX86BranchTest("jnz", :byte)
851 $asm.puts
"jmp #{operands[0].x86CallOperand(:ptr)}"
853 handleX86OpBranch("addl", "jo", :int)
855 handleX86OpBranch("add#{x86Suffix(:ptr)}", "jo", :ptr)
857 handleX86OpBranch("addl", "js", :int)
859 handleX86OpBranch("add#{x86Suffix(:ptr)}", "js", :ptr)
861 handleX86OpBranch("addl", "jz", :int)
863 handleX86OpBranch("add#{x86Suffix(:ptr)}", "jz", :ptr)
865 handleX86OpBranch("addl", "jnz", :int)
867 handleX86OpBranch("add#{x86Suffix(:ptr)}", "jnz", :ptr)
869 handleX86SubBranch("jo", :int)
871 handleX86SubBranch("js", :int)
873 handleX86SubBranch("jz", :int)
875 handleX86SubBranch("jnz", :int)
877 handleX86OpBranch("imull", "jo", :int)
879 handleX86OpBranch("imull", "js", :int)
881 handleX86OpBranch("imull", "jz", :int)
883 handleX86OpBranch("imull", "jnz", :int)
885 handleX86OpBranch("orl", "jo", :int)
887 handleX86OpBranch("orl", "js", :int)
889 handleX86OpBranch("orl", "jz", :int)
891 handleX86OpBranch("orl", "jnz", :int)
895 $asm.puts
"call #{operands[0].x86CallOperand(:ptr)}"
899 handleX86IntCompareSet("sete", :int)
901 handleX86IntCompareSet("sete", :byte)
903 handleX86IntCompareSet("sete", :ptr)
905 handleX86IntCompareSet("setne", :int)
907 handleX86IntCompareSet("setne", :byte)
909 handleX86IntCompareSet("setne", :ptr)
911 handleX86IntCompareSet("seta", :int)
913 handleX86IntCompareSet("seta", :byte)
915 handleX86IntCompareSet("seta", :ptr)
917 handleX86IntCompareSet("setae", :int)
919 handleX86IntCompareSet("setae", :byte)
921 handleX86IntCompareSet("setae", :ptr)
923 handleX86IntCompareSet("setb", :int)
925 handleX86IntCompareSet("setb", :byte)
927 handleX86IntCompareSet("setb", :ptr)
929 handleX86IntCompareSet("setbe", :int)
931 handleX86IntCompareSet("setbe", :byte)
933 handleX86IntCompareSet("setbe", :ptr)
935 handleX86IntCompareSet("setg", :int)
937 handleX86IntCompareSet("setg", :byte)
939 handleX86IntCompareSet("setg", :ptr)
941 handleX86IntCompareSet("setge", :int)
943 handleX86IntCompareSet("setge", :byte)
945 handleX86IntCompareSet("setge", :ptr)
947 handleX86IntCompareSet("setl", :int)
949 handleX86IntCompareSet("setl", :byte)
951 handleX86IntCompareSet("setl", :ptr)
953 handleX86IntCompareSet("setle", :int)
955 handleX86IntCompareSet("setle", :byte)
957 handleX86IntCompareSet("setle", :ptr)
959 handleX86SetTest("seto", :int)
961 handleX86SetTest("sets", :int)
963 handleX86SetTest("setz", :int)
965 handleX86SetTest("setnz", :int)
967 handleX86SetTest("seto", :ptr)
969 handleX86SetTest("sets", :ptr)
971 handleX86SetTest("setz", :ptr)
973 handleX86SetTest("setnz", :ptr)
975 handleX86SetTest("seto", :byte)
977 handleX86SetTest("sets", :byte)
979 handleX86SetTest("setz", :byte)
981 handleX86SetTest("setnz", :byte)
983 sp
= RegisterID
.new(nil, "sp")
984 $asm.puts
"mov#{x86Suffix(:ptr)} #{operands[0].value * x86Bytes(:ptr)}(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:ptr)}"
986 sp
= RegisterID
.new(nil, "sp")
987 $asm.puts
"mov#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{operands[1].value * x86Bytes(:ptr)}(#{sp.x86Operand(:ptr)})"
991 $asm.puts
"idivl #{operands[0].x86Operand(:int)}"
993 $asm.puts
"movd #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:double)}"
994 $asm.puts
"movd #{operands[1].x86Operand(:int)}, %xmm7"
995 $asm.puts
"psllq $32, %xmm7"
996 $asm.puts
"por %xmm7, #{operands[2].x86Operand(:double)}"
998 $asm.puts
"movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
999 $asm.puts
"movsd #{operands[0].x86Operand(:double)}, %xmm7"
1000 $asm.puts
"psrlq $32, %xmm7"
1001 $asm.puts
"movsd %xmm7, #{operands[2].x86Operand(:int)}"
1003 $asm.puts
"movd #{operands[0].x86Operand(:ptr)}, #{operands[1].x86Operand(:double)}"
1005 $asm.puts
"movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:ptr)}"
1007 $asm.puts
"jo #{operands[0].asmLabel}"
1009 $asm.puts
"js #{operands[0].asmLabel}"
1011 $asm.puts
"jz #{operands[0].asmLabel}"
1013 $asm.puts
"jnz #{operands[0].asmLabel}"
1015 $asm.puts
"leal #{operands[0].x86AddressOperand(:int)}, #{operands[1].x86Operand(:int)}"
1017 $asm.puts
"lea#{x86Suffix(:ptr)} #{operands[0].x86AddressOperand(:ptr)}, #{operands[1].x86Operand(:ptr)}"
1019 raise "Bad opcode: #{opcode}"