Refactor LLInt64 to distinguish the pointer operations from the 64-bit integer operations
https://bugs.webkit.org/show_bug.cgi?id=100321

Reviewed by Filip Pizlo.

We have refactored the MacroAssembler and JIT compilers to distinguish
the pointer operations from the 64-bit integer operations (see bug #99154).
Now we want to do the similar work for LLInt, and the goal is same as
the one mentioned in 99154.

This is the first part of the modification: in the offline assembler,
adding the support of the "<foo>q" instructions which will be used for
64-bit integer operations.

* llint/LowLevelInterpreter.cpp:
(JSC::CLoop::execute):
* offlineasm/cloop.rb:
* offlineasm/instructions.rb:
* offlineasm/x86.rb:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@132445 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index b83612b7..239e48c 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,25 @@
+2012-10-24  Yuqiang Xian  <yuqiang.xian@intel.com>
+
+        Refactor LLInt64 to distinguish the pointer operations from the 64-bit integer operations
+        https://bugs.webkit.org/show_bug.cgi?id=100321
+
+        Reviewed by Filip Pizlo.
+
+        We have refactored the MacroAssembler and JIT compilers to distinguish
+        the pointer operations from the 64-bit integer operations (see bug #99154).
+        Now we want to do the similar work for LLInt, and the goal is same as
+        the one mentioned in 99154.
+
+        This is the first part of the modification: in the offline assembler,
+        adding the support of the "<foo>q" instructions which will be used for
+        64-bit integer operations.
+
+        * llint/LowLevelInterpreter.cpp:
+        (JSC::CLoop::execute):
+        * offlineasm/cloop.rb:
+        * offlineasm/instructions.rb:
+        * offlineasm/x86.rb:
+
 2012-10-24  Filip Pizlo  <fpizlo@apple.com>
 
         DFG compileBlahBlahByVal methods for Contiguous and ArrayStorage have only one caller and should be removed
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp b/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
index ebfdadf..c15d431 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
@@ -178,6 +178,7 @@
         NativeFunction nativeFunc;
 #if USE(JSVALUE64)
         int64_t i64;
+        uint64_t u64;
         EncodedJSValue encodedJSValue;
         double castToDouble;
 #endif
diff --git a/Source/JavaScriptCore/offlineasm/cloop.rb b/Source/JavaScriptCore/offlineasm/cloop.rb
index b3e319c..cbc10d2 100644
--- a/Source/JavaScriptCore/offlineasm/cloop.rb
+++ b/Source/JavaScriptCore/offlineasm/cloop.rb
@@ -37,6 +37,8 @@
     when :uint;           ".u"
     when :int32;          ".i32"
     when :uint32;         ".u32"
+    when :int64;          ".i64"
+    when :uint64;         ".u64"
     when :int8;           ".i8"
     when :uint8;          ".u8"
     when :int8Ptr;        ".i8p"
@@ -141,9 +143,11 @@
         case type
         when :int8;    "int8_t(#{valueStr})"
         when :int32;   "int32_t(#{valueStr})"
+        when :int64;   "int64_t(#{valueStr})"
         when :int;     "intptr_t(#{valueStr})"
         when :uint8;   "uint8_t(#{valueStr})"
         when :uint32;  "uint32_t(#{valueStr})"
+        when :uint64;  "uint64_t(#{valueStr})"
         when :uint;    "uintptr_t(#{valueStr})"
         else
             raise "Not implemented immediate of type: #{type}" 
@@ -159,9 +163,11 @@
         case type
         when :int8;         int8MemRef
         when :int32;        int32MemRef
+        when :int64;        int64MemRef
         when :int;          intMemRef
         when :uint8;        uint8MemRef
         when :uint32;       uint32MemRef
+        when :uint64;       uint64MemRef
         when :uint;         uintMemRef
         when :opcode;       opcodeMemRef
         when :nativeFunc;   nativeFuncMemRef
@@ -190,6 +196,9 @@
     def int32MemRef
         "*CAST<int32_t*>(#{pointerExpr})"
     end
+    def int64MemRef
+        "*CAST<int64_t*>(#{pointerExpr})"
+    end
     def intMemRef
         "*CAST<intptr_t*>(#{pointerExpr})"
     end
@@ -202,6 +211,9 @@
     def uint32MemRef
         "*CAST<uint32_t*>(#{pointerExpr})"
     end
+    def uint64MemRef
+        "*CAST<uint64_t*>(#{pointerExpr})"
+    end
     def uintMemRef
         "*CAST<uintptr_t*>(#{pointerExpr})"
     end
@@ -224,9 +236,11 @@
         case type
         when :int8;       int8MemRef
         when :int32;      int32MemRef
+        when :int64;      int64MemRef
         when :int;        intMemRef
         when :uint8;      uint8MemRef
         when :uint32;     uint32MemRef
+        when :uint64;     uint64MemRef
         when :uint;       uintMemRef
         when :opcode;     opcodeMemRef
         else
@@ -250,6 +264,9 @@
     def int32MemRef
         "*CAST<int32_t*>(#{pointerExpr})"
     end
+    def int64MemRef
+        "*CAST<int64_t*>(#{pointerExpr})"
+    end
     def intMemRef
         "*CAST<intptr_t*>(#{pointerExpr})"
     end
@@ -262,6 +279,9 @@
     def uint32MemRef
         "*CAST<uint32_t*>(#{pointerExpr})"
     end
+    def uint64MemRef
+        "*CAST<uint64_t*>(#{pointerExpr})"
+    end
     def uintMemRef
         "*CAST<uintptr_t*>(#{pointerExpr})"
     end
@@ -410,6 +430,7 @@
     case type
     when :int;   tempType = "intptr_t"
     when :int32; tempType = "int32_t"
+    when :int64; tempType = "int64_t"
     else
         raise "Unimplemented type"
     end
@@ -512,51 +533,71 @@
         case opcode
         when "addi"
             cloopEmitOperation(operands, :int32, "+")
+        when "addq"
+            cloopEmitOperation(operands, :int64, "+")
         when "addp"
             cloopEmitOperation(operands, :int, "+")
 
         when "andi"
             cloopEmitOperation(operands, :int32, "&")
+        when "andq"
+            cloopEmitOperation(operands, :int64, "&")
         when "andp"
             cloopEmitOperation(operands, :int, "&")
 
         when "ori"
             cloopEmitOperation(operands, :int32, "|")
+        when "orq"
+            cloopEmitOperation(operands, :int64, "|")
         when "orp"
             cloopEmitOperation(operands, :int, "|")
 
         when "xori"
             cloopEmitOperation(operands, :int32, "^")
+        when "xorq"
+            cloopEmitOperation(operands, :int64, "^")
         when "xorp"
             cloopEmitOperation(operands, :int, "^")
 
         when "lshifti"
             cloopEmitShiftOperation(operands, :int32, "<<")
+        when "lshiftq"
+            cloopEmitShiftOperation(operands, :int64, "<<")
         when "lshiftp"
             cloopEmitShiftOperation(operands, :int, "<<")
 
         when "rshifti"
             cloopEmitShiftOperation(operands, :int32, ">>")
+        when "rshiftq"
+            cloopEmitShiftOperation(operands, :int64, ">>")
         when "rshiftp"
             cloopEmitShiftOperation(operands, :int, ">>")
 
         when "urshifti"
             cloopEmitShiftOperation(operands, :uint32, ">>")
+        when "urshiftq"
+            cloopEmitShiftOperation(operands, :uint64, ">>")
         when "urshiftp"
             cloopEmitShiftOperation(operands, :uint, ">>")
 
         when "muli"
             cloopEmitOperation(operands, :int32, "*")
+        when "mulq"
+            cloopEmitOperation(operands, :int64, "*")
         when "mulp"
             cloopEmitOperation(operands, :int, "*")
 
         when "subi"
             cloopEmitOperation(operands, :int32, "-")
+        when "subq"
+            cloopEmitOperation(operands, :int64, "-")
         when "subp"
             cloopEmitOperation(operands, :int, "-")
 
         when "negi"
             $asm.putc "#{operands[0].clValue(:int32)} = -#{operands[0].clValue(:int32)};"
+        when "negq"
+            $asm.putc "#{operands[0].clValue(:int64)} = -#{operands[0].clValue(:int64)};"
         when "negp"
             $asm.putc "#{operands[0].clValue(:int)} = -#{operands[0].clValue(:int)};"
 
@@ -567,10 +608,14 @@
             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].uint32MemRef};"
         when "loadis"
             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].int32MemRef};"
+        when "loadq"
+            $asm.putc "#{operands[1].clValue(:int64)} = #{operands[0].int64MemRef};"
         when "loadp"
             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].intMemRef};"
         when "storei"
             $asm.putc "#{operands[1].int32MemRef} = #{operands[0].clValue(:int32)};"
+        when "storeq"
+            $asm.putc "#{operands[1].int64MemRef} = #{operands[0].clValue(:int64)};"
         when "storep"
             $asm.putc "#{operands[1].intMemRef} = #{operands[0].clValue(:int)};"
         when "loadb"
@@ -647,12 +692,18 @@
             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].clValue(:int32)};"
         when "zxi2p"
             $asm.putc "#{operands[1].clValue(:uint)} = #{operands[0].clValue(:uint32)};"
+        when "sxi2q"
+            $asm.putc "#{operands[1].clValue(:int64)} = #{operands[0].clValue(:int32)};"
+        when "zxi2q"
+            $asm.putc "#{operands[1].clValue(:uint64)} = #{operands[0].clValue(:uint32)};"
         when "nop"
             $asm.putc "// nop"
         when "bbeq"
             cloopEmitCompareAndBranch(operands, :int8, "==")
         when "bieq"
             cloopEmitCompareAndBranch(operands, :int32, "==")
+        when "bqeq"
+            cloopEmitCompareAndBranch(operands, :int64, "==")
         when "bpeq"
             cloopEmitCompareAndBranch(operands, :int, "==")
 
@@ -660,6 +711,8 @@
             cloopEmitCompareAndBranch(operands, :int8, "!=")
         when "bineq"
             cloopEmitCompareAndBranch(operands, :int32, "!=")
+        when "bqneq"
+            cloopEmitCompareAndBranch(operands, :int64, "!=")
         when "bpneq"
             cloopEmitCompareAndBranch(operands, :int, "!=")
 
@@ -667,6 +720,8 @@
             cloopEmitCompareAndBranch(operands, :uint8, ">")
         when "bia"
             cloopEmitCompareAndBranch(operands, :uint32, ">")
+        when "bqa"
+            cloopEmitCompareAndBranch(operands, :uint64, ">")
         when "bpa"
             cloopEmitCompareAndBranch(operands, :uint, ">")
 
@@ -674,6 +729,8 @@
             cloopEmitCompareAndBranch(operands, :uint8, ">=")
         when "biaeq"
             cloopEmitCompareAndBranch(operands, :uint32, ">=")
+        when "bqaeq"
+            cloopEmitCompareAndBranch(operands, :uint64, ">=")
         when "bpaeq"
             cloopEmitCompareAndBranch(operands, :uint, ">=")
 
@@ -681,6 +738,8 @@
             cloopEmitCompareAndBranch(operands, :uint8, "<")
         when "bib"
             cloopEmitCompareAndBranch(operands, :uint32, "<")
+        when "bqb"
+            cloopEmitCompareAndBranch(operands, :uint64, "<")
         when "bpb"
             cloopEmitCompareAndBranch(operands, :uint, "<")
 
@@ -688,6 +747,8 @@
             cloopEmitCompareAndBranch(operands, :uint8, "<=")
         when "bibeq"
             cloopEmitCompareAndBranch(operands, :uint32, "<=")
+        when "bqbeq"
+            cloopEmitCompareAndBranch(operands, :uint64, "<=")
         when "bpbeq"
             cloopEmitCompareAndBranch(operands, :uint, "<=")
 
@@ -695,6 +756,8 @@
             cloopEmitCompareAndBranch(operands, :int8, ">")
         when "bigt"
             cloopEmitCompareAndBranch(operands, :int32, ">")
+        when "bqgt"
+            cloopEmitCompareAndBranch(operands, :int64, ">")
         when "bpgt"
             cloopEmitCompareAndBranch(operands, :int, ">")
 
@@ -702,6 +765,8 @@
             cloopEmitCompareAndBranch(operands, :int8, ">=")
         when "bigteq"
             cloopEmitCompareAndBranch(operands, :int32, ">=")
+        when "bqgteq"
+            cloopEmitCompareAndBranch(operands, :int64, ">=")
         when "bpgteq"
             cloopEmitCompareAndBranch(operands, :int, ">=")
 
@@ -709,6 +774,8 @@
             cloopEmitCompareAndBranch(operands, :int8, "<")
         when "bilt"
             cloopEmitCompareAndBranch(operands, :int32, "<")
+        when "bqlt"
+            cloopEmitCompareAndBranch(operands, :int64, "<")
         when "bplt"
             cloopEmitCompareAndBranch(operands, :int, "<")
 
@@ -716,6 +783,8 @@
             cloopEmitCompareAndBranch(operands, :int8, "<=")
         when "bilteq"
             cloopEmitCompareAndBranch(operands, :int32, "<=")
+        when "bqlteq"
+            cloopEmitCompareAndBranch(operands, :int64, "<=")
         when "bplteq"
             cloopEmitCompareAndBranch(operands, :int, "<=")
 
@@ -723,6 +792,8 @@
             cloopEmitTestAndBranchIf(operands, :int8, "== 0", operands[-1].cLabel)
         when "btiz"
             cloopEmitTestAndBranchIf(operands, :int32, "== 0", operands[-1].cLabel)
+        when "btqz"
+            cloopEmitTestAndBranchIf(operands, :int64, "== 0", operands[-1].cLabel)
         when "btpz"
             cloopEmitTestAndBranchIf(operands, :int, "== 0", operands[-1].cLabel)
 
@@ -730,6 +801,8 @@
             cloopEmitTestAndBranchIf(operands, :int8, "!= 0", operands[-1].cLabel)
         when "btinz"
             cloopEmitTestAndBranchIf(operands, :int32, "!= 0", operands[-1].cLabel)
+        when "btqnz"
+            cloopEmitTestAndBranchIf(operands, :int64, "!= 0", operands[-1].cLabel)
         when "btpnz"
             cloopEmitTestAndBranchIf(operands, :int, "!= 0", operands[-1].cLabel)
 
@@ -737,6 +810,8 @@
             cloopEmitTestAndBranchIf(operands, :int8, "< 0", operands[-1].cLabel)
         when "btis"
             cloopEmitTestAndBranchIf(operands, :int32, "< 0", operands[-1].cLabel)
+        when "btqs"
+            cloopEmitTestAndBranchIf(operands, :int64, "< 0", operands[-1].cLabel)
         when "btps"
             cloopEmitTestAndBranchIf(operands, :int, "< 0", operands[-1].cLabel)
 
@@ -770,6 +845,8 @@
             cloopEmitCompareAndSet(operands, :uint8, "==")
         when "cieq"
             cloopEmitCompareAndSet(operands, :uint32, "==")
+        when "cqeq"
+            cloopEmitCompareAndSet(operands, :uint64, "==")
         when "cpeq"
             cloopEmitCompareAndSet(operands, :uint, "==")
 
@@ -777,6 +854,8 @@
             cloopEmitCompareAndSet(operands, :uint8, "!=")
         when "cineq"
             cloopEmitCompareAndSet(operands, :uint32, "!=")
+        when "cqneq"
+            cloopEmitCompareAndSet(operands, :uint64, "!=")
         when "cpneq"
             cloopEmitCompareAndSet(operands, :uint, "!=")
 
@@ -784,6 +863,8 @@
             cloopEmitCompareAndSet(operands, :uint8, ">")
         when "cia"
             cloopEmitCompareAndSet(operands, :uint32, ">")
+        when "cqa"
+            cloopEmitCompareAndSet(operands, :uint64, ">")
         when "cpa"
             cloopEmitCompareAndSet(operands, :uint, ">")
 
@@ -791,6 +872,8 @@
             cloopEmitCompareAndSet(operands, :uint8, ">=")
         when "ciaeq"
             cloopEmitCompareAndSet(operands, :uint32, ">=")
+        when "cqaeq"
+            cloopEmitCompareAndSet(operands, :uint64, ">=")
         when "cpaeq"
             cloopEmitCompareAndSet(operands, :uint, ">=")
 
@@ -798,6 +881,8 @@
             cloopEmitCompareAndSet(operands, :uint8, "<")
         when "cib"
             cloopEmitCompareAndSet(operands, :uint32, "<")
+        when "cqb"
+            cloopEmitCompareAndSet(operands, :uint64, "<")
         when "cpb"
             cloopEmitCompareAndSet(operands, :uint, "<")
 
@@ -805,6 +890,8 @@
             cloopEmitCompareAndSet(operands, :uint8, "<=")
         when "cibeq"
             cloopEmitCompareAndSet(operands, :uint32, "<=")
+        when "cqbeq"
+            cloopEmitCompareAndSet(operands, :uint64, "<=")
         when "cpbeq"
             cloopEmitCompareAndSet(operands, :uint, "<=")
 
@@ -812,6 +899,8 @@
             cloopEmitCompareAndSet(operands, :int8, ">")
         when "cigt"
             cloopEmitCompareAndSet(operands, :int32, ">")
+        when "cqgt"
+            cloopEmitCompareAndSet(operands, :int64, ">")
         when "cpgt"
             cloopEmitCompareAndSet(operands, :int, ">")
 
@@ -819,6 +908,8 @@
             cloopEmitCompareAndSet(operands, :int8, ">=")
         when "cigteq"
             cloopEmitCompareAndSet(operands, :int32, ">=")
+        when "cqgteq"
+            cloopEmitCompareAndSet(operands, :int64, ">=")
         when "cpgteq"
             cloopEmitCompareAndSet(operands, :int, ">=")
 
@@ -826,6 +917,8 @@
             cloopEmitCompareAndSet(operands, :int8, "<")
         when "cilt"
             cloopEmitCompareAndSet(operands, :int32, "<")
+        when "cqlt"
+            cloopEmitCompareAndSet(operands, :int64, "<")
         when "cplt"
             cloopEmitCompareAndSet(operands, :int, "<")
 
@@ -833,6 +926,8 @@
             cloopEmitCompareAndSet(operands, :int8, "<=")
         when "cilteq"
             cloopEmitCompareAndSet(operands, :int32, "<=")
+        when "cqlteq"
+            cloopEmitCompareAndSet(operands, :int64, "<=")
         when "cplteq"
             cloopEmitCompareAndSet(operands, :int, "<=")
 
@@ -840,6 +935,8 @@
             cloopEmitTestSet(operands, :int8, "< 0")
         when "tis"
             cloopEmitTestSet(operands, :int32, "< 0")
+        when "tqs"
+            cloopEmitTestSet(operands, :int64, "< 0")
         when "tps"
             cloopEmitTestSet(operands, :int, "< 0")
 
@@ -847,6 +944,8 @@
             cloopEmitTestSet(operands, :int8, "== 0")
         when "tiz"
             cloopEmitTestSet(operands, :int32, "== 0")
+        when "tqz"
+            cloopEmitTestSet(operands, :int64, "== 0")
         when "tpz"
             cloopEmitTestSet(operands, :int, "== 0")
 
@@ -854,6 +953,8 @@
             cloopEmitTestSet(operands, :int8, "!= 0")
         when "tinz"
             cloopEmitTestSet(operands, :int32, "!= 0")
+        when "tqnz"
+            cloopEmitTestSet(operands, :int64, "!= 0")
         when "tpnz"
             cloopEmitTestSet(operands, :int, "!= 0")
 
@@ -897,14 +998,14 @@
         when "fd2ii"
             $asm.putc "Double2Ints(#{operands[0].clValue(:double)}, #{operands[1].clValue}, #{operands[2].clValue});"
 
-        # 64-bit instruction: fp2d int64Op dblOp (based on X64)
+        # 64-bit instruction: fq2d int64Op dblOp (based on X64)
         # Copy a bit-encoded double in a 64-bit int register to a double register.
-        when "fp2d"
+        when "fq2d", "fp2d"
             $asm.putc "#{operands[1].clValue(:double)} = #{operands[0].clValue(:castToDouble)};"
 
-        # 64-bit instruction: fd2p dblOp int64Op (based on X64 instruction set)
+        # 64-bit instruction: fd2q dblOp int64Op (based on X64 instruction set)
         # Copy a double as a bit-encoded double into a 64-bit int register.
-        when "fd2p"
+        when "fd2q", "fd2p"
             $asm.putc "#{operands[1].clValue(:voidPtr)} = #{operands[0].clValue(:castToVoidPtr)};"
 
         when "leai"
@@ -926,6 +1027,13 @@
         when "baddinz"
             cloopEmitOpAndBranch(operands, "+", :int32, "!= 0")
 
+        when "baddqs"
+            cloopEmitOpAndBranch(operands, "+", :int64, "< 0")
+        when "baddqz"
+            cloopEmitOpAndBranch(operands, "+", :int64, "== 0")
+        when "baddqnz"
+            cloopEmitOpAndBranch(operands, "+", :int64, "!= 0")
+
         when "baddps"
             cloopEmitOpAndBranch(operands, "+", :int, "< 0")
         when "baddpz"
diff --git a/Source/JavaScriptCore/offlineasm/instructions.rb b/Source/JavaScriptCore/offlineasm/instructions.rb
index ddb1bb9..8b23907 100644
--- a/Source/JavaScriptCore/offlineasm/instructions.rb
+++ b/Source/JavaScriptCore/offlineasm/instructions.rb
@@ -33,15 +33,19 @@
      "andi",
      "lshifti",
      "lshiftp",
+     "lshiftq",
      "muli",
      "negi",
      "negp",
+     "negq",
      "noti",
      "ori",
      "rshifti",
      "urshifti",
      "rshiftp",
      "urshiftp",
+     "rshiftq",
+     "urshiftq",
      "subi",
      "xori",
      "loadi",
@@ -65,6 +69,8 @@
      "fd2ii", # usage: fd2ii <fpr>, <gpr with least significant bits>, <gpr with most significant bits>
      "fp2d",
      "fd2p",
+     "fq2d",
+     "fd2q",
      "bdeq",
      "bdneq",
      "bdgt",
@@ -86,6 +92,8 @@
      "move",
      "sxi2p",
      "zxi2p",
+     "sxi2q",
+     "zxi2q",
      "nop",
      "bieq",
      "bineq",
@@ -199,6 +207,46 @@
      "baddps",
      "baddpz",
      "baddpnz",
+     "tqs",
+     "tqz",
+     "tqnz",
+     "peekq",
+     "pokeq",
+     "bqeq",
+     "bqneq",
+     "bqa",
+     "bqaeq",
+     "bqb",
+     "bqbeq",
+     "bqgt",
+     "bqgteq",
+     "bqlt",
+     "bqlteq",
+     "addq",
+     "mulq",
+     "andq",
+     "orq",
+     "subq",
+     "xorq",
+     "loadq",
+     "cqeq",
+     "cqneq",
+     "cqa",
+     "cqaeq",
+     "cqb",
+     "cqbeq",
+     "cqgt",
+     "cqgteq",
+     "cqlt",
+     "cqlteq",
+     "storeq",
+     "btqs",
+     "btqz",
+     "btqnz",
+     "baddqo",
+     "baddqs",
+     "baddqz",
+     "baddqnz",
      "bo",
      "bs",
      "bz",
diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb
index 033c200..d3f8ade 100644
--- a/Source/JavaScriptCore/offlineasm/x86.rb
+++ b/Source/JavaScriptCore/offlineasm/x86.rb
@@ -45,12 +45,15 @@
             "%" + @name + "d"
         when :ptr
             "%" + @name
+        when :quad
+            "%" + @name
         else
             raise
         end
     end
     def x86CallOperand(kind)
-        "*#{x86Operand(kind)}"
+        # Call operands are not allowed to be partial registers.
+        "*#{x86Operand(:quad)}"
     end
 end
 
@@ -82,6 +85,8 @@
                 "%eax"
             when :ptr
                 isX64 ? "%rax" : "%eax"
+            when :quad
+                isX64 ? "%rax" : raise
             else
                 raise
             end
@@ -95,6 +100,8 @@
                 "%edx"
             when :ptr
                 isX64 ? "%rdx" : "%edx"
+            when :quad
+                isX64 ? "%rdx" : raise
             else
                 raise
             end
@@ -108,6 +115,8 @@
                 "%ecx"
             when :ptr
                 isX64 ? "%rcx" : "%ecx"
+            when :quad
+                isX64 ? "%rcx" : raise
             else
                 raise
             end
@@ -121,6 +130,8 @@
                 "%ebx"
             when :ptr
                 isX64 ? "%rbx" : "%ebx"
+            when :quad
+                isX64 ? "%rbx" : raise
             else
                 raise
             end
@@ -134,6 +145,8 @@
                 "%esi"
             when :ptr
                 isX64 ? "%rsi" : "%esi"
+            when :quad
+                isX64 ? "%rsi" : raise
             else
                 raise
             end
@@ -146,6 +159,8 @@
                     "%r13d"
                 when :ptr
                     "%r13"
+                when :quad
+                    "%r13"
                 else
                     raise
                 end
@@ -173,6 +188,8 @@
                 "%esp"
             when :ptr
                 isX64 ? "%rsp" : "%esp"
+            when :quad
+                isX64 ? "%rsp" : raise
             else
                 raise
             end
@@ -187,6 +204,8 @@
                 "%edi"
             when :ptr
                 "%rdi"
+            when :quad
+                "%rdi"
             end
         when "t6"
             raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
@@ -197,6 +216,8 @@
                 "%r10d"
             when :ptr
                 "%r10"
+            when :quad
+                "%r10"
             end
         when "csr1"
             raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
@@ -207,6 +228,8 @@
                 "%r14d"
             when :ptr
                 "%r14"
+            when :quad
+                "%r14"
             end
         when "csr2"
             raise "Cannot use #{name} in 32-bit X86 at #{codeOriginString}" unless isX64
@@ -217,13 +240,15 @@
                 "%r15d"
             when :ptr
                 "%r15"
+            when :quad
+                "%r15"
             end
         else
             raise "Bad register #{name} for X86 at #{codeOriginString}"
         end
     end
     def x86CallOperand(kind)
-        "*#{x86Operand(kind)}"
+        isX64 ? "*#{x86Operand(:quad)}" : "*#{x86Operand(:ptr)}"
     end
 end
 
@@ -394,6 +419,8 @@
             "l"
         when :ptr
             isX64 ? "q" : "l"
+        when :quad
+            isX64 ? "q" : raise
         when :double
             "sd"
         else
@@ -411,6 +438,8 @@
             4
         when :ptr
             isX64 ? 8 : 4
+        when :quad
+            isX64 ? 8 : raise
         when :double
             8
         else
@@ -607,9 +636,17 @@
     
     def handleMove
         if Immediate.new(nil, 0) == operands[0] and operands[1].is_a? RegisterID
-            $asm.puts "xor#{x86Suffix(:ptr)} #{operands[1].x86Operand(:ptr)}, #{operands[1].x86Operand(:ptr)}"
+            if isX64
+                $asm.puts "xor#{x86Suffix(:quad)} #{operands[1].x86Operand(:quad)}, #{operands[1].x86Operand(:quad)}"
+            else
+                $asm.puts "xor#{x86Suffix(:ptr)} #{operands[1].x86Operand(:ptr)}, #{operands[1].x86Operand(:ptr)}"
+            end
         elsif operands[0] != operands[1]
-            $asm.puts "mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}"
+            if isX64
+                $asm.puts "mov#{x86Suffix(:quad)} #{x86Operands(:quad, :quad)}"
+            else
+                $asm.puts "mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}"
+            end
         end
     end
     
@@ -632,54 +669,76 @@
             handleX86Add(:int)
         when "addp"
             handleX86Add(:ptr)
+        when "addq"
+            handleX86Add(:quad)
         when "andi"
             handleX86Op("andl", :int)
         when "andp"
             handleX86Op("and#{x86Suffix(:ptr)}", :ptr)
+        when "andq"
+            handleX86Op("and#{x86Suffix(:quad)}", :quad)
         when "lshifti"
             handleX86Shift("sall", :int)
         when "lshiftp"
             handleX86Shift("sal#{x86Suffix(:ptr)}", :ptr)
+        when "lshiftq"
+            handleX86Shift("sal#{x86Suffix(:quad)}", :quad)
         when "muli"
             handleX86Mul(:int)
         when "mulp"
             handleX86Mul(:ptr)
+        when "mulq"
+            handleX86Mul(:quad)
         when "negi"
             $asm.puts "negl #{x86Operands(:int)}"
         when "negp"
             $asm.puts "neg#{x86Suffix(:ptr)} #{x86Operands(:ptr)}"
+        when "negq"
+            $asm.puts "neg#{x86Suffix(:quad)} #{x86Operands(:quad)}"
         when "noti"
             $asm.puts "notl #{x86Operands(:int)}"
         when "ori"
             handleX86Op("orl", :int)
         when "orp"
             handleX86Op("or#{x86Suffix(:ptr)}", :ptr)
+        when "orq"
+            handleX86Op("or#{x86Suffix(:quad)}", :quad)
         when "rshifti"
             handleX86Shift("sarl", :int)
         when "rshiftp"
             handleX86Shift("sar#{x86Suffix(:ptr)}", :ptr)
+        when "rshiftq"
+            handleX86Shift("sar#{x86Suffix(:quad)}", :quad)
         when "urshifti"
             handleX86Shift("shrl", :int)
         when "urshiftp"
             handleX86Shift("shr#{x86Suffix(:ptr)}", :ptr)
+        when "urshiftq"
+            handleX86Shift("shr#{x86Suffix(:quad)}", :quad)
         when "subi"
             handleX86Sub(:int)
         when "subp"
             handleX86Sub(:ptr)
+        when "subq"
+            handleX86Sub(:quad)
         when "xori"
             handleX86Op("xorl", :int)
         when "xorp"
             handleX86Op("xor#{x86Suffix(:ptr)}", :ptr)
+        when "xorq"
+            handleX86Op("xor#{x86Suffix(:quad)}", :quad)
         when "loadi", "storei"
             $asm.puts "movl #{x86Operands(:int, :int)}"
         when "loadis"
             if isX64
-                $asm.puts "movslq #{x86Operands(:int, :ptr)}"
+                $asm.puts "movslq #{x86Operands(:int, :quad)}"
             else
                 $asm.puts "movl #{x86Operands(:int, :int)}"
             end
         when "loadp", "storep"
             $asm.puts "mov#{x86Suffix(:ptr)} #{x86Operands(:ptr, :ptr)}"
+        when "loadq", "storeq"
+            $asm.puts "mov#{x86Suffix(:quad)} #{x86Operands(:quad, :quad)}"
         when "loadb"
             $asm.puts "movzbl #{operands[0].x86Operand(:byte)}, #{operands[1].x86Operand(:int)}"
         when "loadbs"
@@ -763,7 +822,7 @@
             handleMove
         when "sxi2p"
             if isX64
-                $asm.puts "movslq #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:ptr)}"
+                $asm.puts "movslq #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:quad)}"
             else
                 handleMove
             end
@@ -773,48 +832,72 @@
             else
                 handleMove
             end
+        when "sxi2q"
+            $asm.puts "movslq #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:quad)}"
+        when "zxi2q"
+            $asm.puts "movl #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
         when "nop"
             $asm.puts "nop"
         when "bieq"
             handleX86IntBranch("je", :int)
         when "bpeq"
             handleX86IntBranch("je", :ptr)
+        when "bqeq"
+            handleX86IntBranch("je", :quad)
         when "bineq"
             handleX86IntBranch("jne", :int)
         when "bpneq"
             handleX86IntBranch("jne", :ptr)
+        when "bqneq"
+            handleX86IntBranch("jne", :quad)
         when "bia"
             handleX86IntBranch("ja", :int)
         when "bpa"
             handleX86IntBranch("ja", :ptr)
+        when "bqa"
+            handleX86IntBranch("ja", :quad)
         when "biaeq"
             handleX86IntBranch("jae", :int)
         when "bpaeq"
             handleX86IntBranch("jae", :ptr)
+        when "bqaeq"
+            handleX86IntBranch("jae", :quad)
         when "bib"
             handleX86IntBranch("jb", :int)
         when "bpb"
             handleX86IntBranch("jb", :ptr)
+        when "bqb"
+            handleX86IntBranch("jb", :quad)
         when "bibeq"
             handleX86IntBranch("jbe", :int)
         when "bpbeq"
             handleX86IntBranch("jbe", :ptr)
+        when "bqbeq"
+            handleX86IntBranch("jbe", :quad)
         when "bigt"
             handleX86IntBranch("jg", :int)
         when "bpgt"
             handleX86IntBranch("jg", :ptr)
+        when "bqgt"
+            handleX86IntBranch("jg", :quad)
         when "bigteq"
             handleX86IntBranch("jge", :int)
         when "bpgteq"
             handleX86IntBranch("jge", :ptr)
+        when "bqgteq"
+            handleX86IntBranch("jge", :quad)
         when "bilt"
             handleX86IntBranch("jl", :int)
         when "bplt"
             handleX86IntBranch("jl", :ptr)
+        when "bqlt"
+            handleX86IntBranch("jl", :quad)
         when "bilteq"
             handleX86IntBranch("jle", :int)
         when "bplteq"
             handleX86IntBranch("jle", :ptr)
+        when "bqlteq"
+            handleX86IntBranch("jle", :quad)
         when "bbeq"
             handleX86IntBranch("je", :byte)
         when "bbneq"
@@ -839,14 +922,20 @@
             handleX86BranchTest("js", :int)
         when "btps"
             handleX86BranchTest("js", :ptr)
+        when "btqs"
+            handleX86BranchTest("js", :quad)
         when "btiz"
             handleX86BranchTest("jz", :int)
         when "btpz"
             handleX86BranchTest("jz", :ptr)
+        when "btqz"
+            handleX86BranchTest("jz", :quad)
         when "btinz"
             handleX86BranchTest("jnz", :int)
         when "btpnz"
             handleX86BranchTest("jnz", :ptr)
+        when "btqnz"
+            handleX86BranchTest("jnz", :quad)
         when "btbs"
             handleX86BranchTest("js", :byte)
         when "btbz"
@@ -859,18 +948,26 @@
             handleX86OpBranch("addl", "jo", :int)
         when "baddpo"
             handleX86OpBranch("add#{x86Suffix(:ptr)}", "jo", :ptr)
+        when "baddqo"
+            handleX86OpBranch("add#{x86Suffix(:quad)}", "jo", :quad)
         when "baddis"
             handleX86OpBranch("addl", "js", :int)
         when "baddps"
             handleX86OpBranch("add#{x86Suffix(:ptr)}", "js", :ptr)
+        when "baddqs"
+            handleX86OpBranch("add#{x86Suffix(:quad)}", "js", :quad)
         when "baddiz"
             handleX86OpBranch("addl", "jz", :int)
         when "baddpz"
             handleX86OpBranch("add#{x86Suffix(:ptr)}", "jz", :ptr)
+        when "baddqz"
+            handleX86OpBranch("add#{x86Suffix(:quad)}", "jz", :quad)
         when "baddinz"
             handleX86OpBranch("addl", "jnz", :int)
         when "baddpnz"
             handleX86OpBranch("add#{x86Suffix(:ptr)}", "jnz", :ptr)
+        when "baddqnz"
+            handleX86OpBranch("add#{x86Suffix(:quad)}", "jnz", :quad)
         when "bsubio"
             handleX86SubBranch("jo", :int)
         when "bsubis"
@@ -907,60 +1004,80 @@
             handleX86IntCompareSet("sete", :byte)
         when "cpeq"
             handleX86IntCompareSet("sete", :ptr)
+        when "cqeq"
+            handleX86IntCompareSet("sete", :quad)
         when "cineq"
             handleX86IntCompareSet("setne", :int)
         when "cbneq"
             handleX86IntCompareSet("setne", :byte)
         when "cpneq"
             handleX86IntCompareSet("setne", :ptr)
+        when "cqneq"
+            handleX86IntCompareSet("setne", :quad)
         when "cia"
             handleX86IntCompareSet("seta", :int)
         when "cba"
             handleX86IntCompareSet("seta", :byte)
         when "cpa"
             handleX86IntCompareSet("seta", :ptr)
+        when "cqa"
+            handleX86IntCompareSet("seta", :quad)
         when "ciaeq"
             handleX86IntCompareSet("setae", :int)
         when "cbaeq"
             handleX86IntCompareSet("setae", :byte)
         when "cpaeq"
             handleX86IntCompareSet("setae", :ptr)
+        when "cqaeq"
+            handleX86IntCompareSet("setae", :quad)
         when "cib"
             handleX86IntCompareSet("setb", :int)
         when "cbb"
             handleX86IntCompareSet("setb", :byte)
         when "cpb"
             handleX86IntCompareSet("setb", :ptr)
+        when "cqb"
+            handleX86IntCompareSet("setb", :quad)
         when "cibeq"
             handleX86IntCompareSet("setbe", :int)
         when "cbbeq"
             handleX86IntCompareSet("setbe", :byte)
         when "cpbeq"
             handleX86IntCompareSet("setbe", :ptr)
+        when "cqbeq"
+            handleX86IntCompareSet("setbe", :quad)
         when "cigt"
             handleX86IntCompareSet("setg", :int)
         when "cbgt"
             handleX86IntCompareSet("setg", :byte)
         when "cpgt"
             handleX86IntCompareSet("setg", :ptr)
+        when "cqgt"
+            handleX86IntCompareSet("setg", :quad)
         when "cigteq"
             handleX86IntCompareSet("setge", :int)
         when "cbgteq"
             handleX86IntCompareSet("setge", :byte)
         when "cpgteq"
             handleX86IntCompareSet("setge", :ptr)
+        when "cqgteq"
+            handleX86IntCompareSet("setge", :quad)
         when "cilt"
             handleX86IntCompareSet("setl", :int)
         when "cblt"
             handleX86IntCompareSet("setl", :byte)
         when "cplt"
             handleX86IntCompareSet("setl", :ptr)
+        when "cqlt"
+            handleX86IntCompareSet("setl", :quad)
         when "cilteq"
             handleX86IntCompareSet("setle", :int)
         when "cblteq"
             handleX86IntCompareSet("setle", :byte)
         when "cplteq"
             handleX86IntCompareSet("setle", :ptr)
+        when "cqlteq"
+            handleX86IntCompareSet("setle", :quad)
         when "tis"
             handleX86SetTest("sets", :int)
         when "tiz"
@@ -973,6 +1090,12 @@
             handleX86SetTest("setz", :ptr)
         when "tpnz"
             handleX86SetTest("setnz", :ptr)
+        when "tqs"
+            handleX86SetTest("sets", :quad)
+        when "tqz"
+            handleX86SetTest("setz", :quad)
+        when "tqnz"
+            handleX86SetTest("setnz", :quad)
         when "tbs"
             handleX86SetTest("sets", :byte)
         when "tbz"
@@ -982,9 +1105,15 @@
         when "peek"
             sp = RegisterID.new(nil, "sp")
             $asm.puts "mov#{x86Suffix(:ptr)} #{operands[0].value * x86Bytes(:ptr)}(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:ptr)}"
+        when "peekq"
+            sp = RegisterID.new(nil, "sp")
+            $asm.puts "mov#{x86Suffix(:quad)} #{operands[0].value * x86Bytes(:quad)}(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:quad)}"
         when "poke"
             sp = RegisterID.new(nil, "sp")
             $asm.puts "mov#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{operands[1].value * x86Bytes(:ptr)}(#{sp.x86Operand(:ptr)})"
+        when "pokeq"
+            sp = RegisterID.new(nil, "sp")
+            $asm.puts "mov#{x86Suffix(:quad)} #{operands[0].x86Operand(:quad)}, #{operands[1].value * x86Bytes(:quad)}(#{sp.x86Operand(:ptr)})"
         when "cdqi"
             $asm.puts "cdq"
         when "idivi"
@@ -999,10 +1128,10 @@
             $asm.puts "movsd #{operands[0].x86Operand(:double)}, %xmm7"
             $asm.puts "psrlq $32, %xmm7"
             $asm.puts "movsd %xmm7, #{operands[2].x86Operand(:int)}"
-        when "fp2d"
-            $asm.puts "movd #{operands[0].x86Operand(:ptr)}, #{operands[1].x86Operand(:double)}"
-        when "fd2p"
-            $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:ptr)}"
+        when "fq2d", "fp2d"
+            $asm.puts "movd #{operands[0].x86Operand(:quad)}, #{operands[1].x86Operand(:double)}"
+        when "fd2q", "fd2p"
+            $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:quad)}"
         when "bo"
             $asm.puts "jo #{operands[0].asmLabel}"
         when "bs"