Support fxsave64 and fxrstor64.
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 4 Dec 2009 07:51:41 +0000 (07:51 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 4 Dec 2009 07:51:41 +0000 (07:51 +0000)
gas/testsuite/

2009-12-03  H.J. Lu  <hongjiu.lu@intel.com>

* gas/i386/i386.exp: Run x86-64-fxsave and x86-64-fxsave-intel.

* gas/i386/rex.d: Updated for fxsave64.

* gas/i386/x86-64-fxsave-intel.d: New.
* gas/i386/x86-64-fxsave.d: Likewise.
* gas/i386/x86-64-fxsave.s: Likewise.

opcodes/

2009-12-03  H.J. Lu  <hongjiu.lu@intel.com>

* i386-dis.c (FXSAVE_Fixup): New.
(FXSAVE): Likewise.
(mod_table): Use FXSAVE on fxsave and fxrstor.

* i386-opc.tbl: Add fxsave64 and fxrstor64.
* i386-tbl.h: Regenerated.

gas/testsuite/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/rex.d
gas/testsuite/gas/i386/x86-64-fxsave-intel.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-fxsave.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-fxsave.s [new file with mode: 0644]
opcodes/ChangeLog
opcodes/i386-dis.c
opcodes/i386-opc.tbl
opcodes/i386-tbl.h

index e045c07..449a183 100644 (file)
@@ -1,3 +1,13 @@
+2009-12-03  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * gas/i386/i386.exp: Run x86-64-fxsave and x86-64-fxsave-intel.
+
+       * gas/i386/rex.d: Updated for fxsave64.
+
+       * gas/i386/x86-64-fxsave-intel.d: New.
+       * gas/i386/x86-64-fxsave.d: Likewise.
+       * gas/i386/x86-64-fxsave.s: Likewise.
+
 2009-12-02  Nick Clifton  <nickc@redhat.com>
            Richard Earnshaw  <rearnsha@arm.com>
 
index 0e6d10b..f4f8a5d 100644 (file)
@@ -304,6 +304,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
       run_dump_test "x86-64-opcode-inval-intel"
     }
     run_dump_test "rexw"
+    run_dump_test "x86-64-fxsave"
+    run_dump_test "x86-64-fxsave-intel"
     run_dump_test "x86-64-arch-1"
     run_dump_test "x86-64-arch-2"
     run_dump_test "x86-64-xsave"
index 97b7854..3548ff2 100644 (file)
@@ -7,13 +7,13 @@ Disassembly of section .text:
 
 0+ <_start>:
 [       ]*[0-9a-f]+:[   ]+40 0f ae 00[  ]+rex fxsave[   ]+\(%rax\)
-[       ]*[0-9a-f]+:[   ]+48 0f ae 00[  ]+rex.W fxsave[         ]+\(%rax\)
+[       ]*[0-9a-f]+:[   ]+48 0f ae 00[  ]+fxsave64[     ]+\(%rax\)
 [       ]*[0-9a-f]+:[   ]+41 0f ae 00[  ]+fxsave[       ]+\(%r8\)
-[       ]*[0-9a-f]+:[   ]+49 0f ae 00[  ]+rex.WB? fxsave[       ]+\(%r8\)
+[       ]*[0-9a-f]+:[   ]+49 0f ae 00[  ]+fxsave64[     ]+\(%r8\)
 [       ]*[0-9a-f]+:[   ]+42 0f ae 04 05 00 00 00 00[   ]+fxsave[       ]+(0x0)?\(,%r8(,1)?\)
-[       ]*[0-9a-f]+:[   ]+4a 0f ae 04 05 00 00 00 00[   ]+rex.WX? fxsave[       ]+(0x0)?\(,%r8(,1)?\)
+[       ]*[0-9a-f]+:[   ]+4a 0f ae 04 05 00 00 00 00[   ]+fxsave64[     ]+(0x0)?\(,%r8(,1)?\)
 [       ]*[0-9a-f]+:[   ]+43 0f ae 04 00[       ]+fxsave[       ]+\(%r8,%r8(,1)?\)
-[       ]*[0-9a-f]+:[   ]+4b 0f ae 04 00[       ]+rex.W(XB)? fxsave[    ]+\(%r8,%r8(,1)?\)
+[       ]*[0-9a-f]+:[   ]+4b 0f ae 04 00[       ]+fxsave64[     ]+\(%r8,%r8(,1)?\)
 [       ]*[0-9a-f]+:[   ]+40 c5 f9 28 00[       ]+rex vmovapd \(%rax\),%xmm0
 [       ]*[0-9a-f]+:[   ]+40[   ]+rex
 [       ]*[0-9a-f]+:[   ]+41[   ]+rex.B
diff --git a/gas/testsuite/gas/i386/x86-64-fxsave-intel.d b/gas/testsuite/gas/i386/x86-64-fxsave-intel.d
new file mode 100644 (file)
index 0000000..6af38d1
--- /dev/null
@@ -0,0 +1,49 @@
+#objdump: -dwMintel
+#name: x86-64 fxsave/fxrstor insns (Intel disassembly)
+#source: x86-64-fxsave.s
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <foo>:
+[      ]*[a-f0-9]+:    0f ae 00                fxsave \[rax\]
+[      ]*[a-f0-9]+:    41 0f ae 00             fxsave \[r8\]
+[      ]*[a-f0-9]+:    41 0f ae 04 00          fxsave \[r8\+rax\*1\]
+[      ]*[a-f0-9]+:    42 0f ae 04 00          fxsave \[rax\+r8\*1\]
+[      ]*[a-f0-9]+:    43 0f ae 04 38          fxsave \[r8\+r15\*1\]
+[      ]*[a-f0-9]+:    48 0f ae 00             fxsave64 \[rax\]
+[      ]*[a-f0-9]+:    49 0f ae 00             fxsave64 \[r8\]
+[      ]*[a-f0-9]+:    49 0f ae 04 00          fxsave64 \[r8\+rax\*1\]
+[      ]*[a-f0-9]+:    4a 0f ae 04 00          fxsave64 \[rax\+r8\*1\]
+[      ]*[a-f0-9]+:    0f ae 08                fxrstor \[rax\]
+[      ]*[a-f0-9]+:    41 0f ae 08             fxrstor \[r8\]
+[      ]*[a-f0-9]+:    41 0f ae 0c 00          fxrstor \[r8\+rax\*1\]
+[      ]*[a-f0-9]+:    42 0f ae 0c 00          fxrstor \[rax\+r8\*1\]
+[      ]*[a-f0-9]+:    43 0f ae 0c 38          fxrstor \[r8\+r15\*1\]
+[      ]*[a-f0-9]+:    48 0f ae 08             fxrstor64 \[rax\]
+[      ]*[a-f0-9]+:    49 0f ae 08             fxrstor64 \[r8\]
+[      ]*[a-f0-9]+:    49 0f ae 0c 00          fxrstor64 \[r8\+rax\*1\]
+[      ]*[a-f0-9]+:    4a 0f ae 0c 00          fxrstor64 \[rax\+r8\*1\]
+[      ]*[a-f0-9]+:    4b 0f ae 0c 38          fxrstor64 \[r8\+r15\*1\]
+[      ]*[a-f0-9]+:    0f ae 00                fxsave \[rax\]
+[      ]*[a-f0-9]+:    41 0f ae 00             fxsave \[r8\]
+[      ]*[a-f0-9]+:    41 0f ae 04 00          fxsave \[r8\+rax\*1\]
+[      ]*[a-f0-9]+:    42 0f ae 04 00          fxsave \[rax\+r8\*1\]
+[      ]*[a-f0-9]+:    43 0f ae 04 38          fxsave \[r8\+r15\*1\]
+[      ]*[a-f0-9]+:    48 0f ae 00             fxsave64 \[rax\]
+[      ]*[a-f0-9]+:    49 0f ae 00             fxsave64 \[r8\]
+[      ]*[a-f0-9]+:    49 0f ae 04 00          fxsave64 \[r8\+rax\*1\]
+[      ]*[a-f0-9]+:    4a 0f ae 04 00          fxsave64 \[rax\+r8\*1\]
+[      ]*[a-f0-9]+:    0f ae 08                fxrstor \[rax\]
+[      ]*[a-f0-9]+:    41 0f ae 08             fxrstor \[r8\]
+[      ]*[a-f0-9]+:    41 0f ae 0c 00          fxrstor \[r8\+rax\*1\]
+[      ]*[a-f0-9]+:    42 0f ae 0c 00          fxrstor \[rax\+r8\*1\]
+[      ]*[a-f0-9]+:    43 0f ae 0c 38          fxrstor \[r8\+r15\*1\]
+[      ]*[a-f0-9]+:    48 0f ae 08             fxrstor64 \[rax\]
+[      ]*[a-f0-9]+:    49 0f ae 08             fxrstor64 \[r8\]
+[      ]*[a-f0-9]+:    49 0f ae 0c 00          fxrstor64 \[r8\+rax\*1\]
+[      ]*[a-f0-9]+:    4a 0f ae 0c 00          fxrstor64 \[rax\+r8\*1\]
+[      ]*[a-f0-9]+:    4b 0f ae 0c 38          fxrstor64 \[r8\+r15\*1\]
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-fxsave.d b/gas/testsuite/gas/i386/x86-64-fxsave.d
new file mode 100644 (file)
index 0000000..5fd9d84
--- /dev/null
@@ -0,0 +1,48 @@
+#objdump: -dw
+#name: x86-64 fxsave/fxrstor insns
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <foo>:
+[      ]*[a-f0-9]+:    0f ae 00                fxsave \(%rax\)
+[      ]*[a-f0-9]+:    41 0f ae 00             fxsave \(%r8\)
+[      ]*[a-f0-9]+:    41 0f ae 04 00          fxsave \(%r8,%rax,1\)
+[      ]*[a-f0-9]+:    42 0f ae 04 00          fxsave \(%rax,%r8,1\)
+[      ]*[a-f0-9]+:    43 0f ae 04 38          fxsave \(%r8,%r15,1\)
+[      ]*[a-f0-9]+:    48 0f ae 00             fxsave64 \(%rax\)
+[      ]*[a-f0-9]+:    49 0f ae 00             fxsave64 \(%r8\)
+[      ]*[a-f0-9]+:    49 0f ae 04 00          fxsave64 \(%r8,%rax,1\)
+[      ]*[a-f0-9]+:    4a 0f ae 04 00          fxsave64 \(%rax,%r8,1\)
+[      ]*[a-f0-9]+:    0f ae 08                fxrstor \(%rax\)
+[      ]*[a-f0-9]+:    41 0f ae 08             fxrstor \(%r8\)
+[      ]*[a-f0-9]+:    41 0f ae 0c 00          fxrstor \(%r8,%rax,1\)
+[      ]*[a-f0-9]+:    42 0f ae 0c 00          fxrstor \(%rax,%r8,1\)
+[      ]*[a-f0-9]+:    43 0f ae 0c 38          fxrstor \(%r8,%r15,1\)
+[      ]*[a-f0-9]+:    48 0f ae 08             fxrstor64 \(%rax\)
+[      ]*[a-f0-9]+:    49 0f ae 08             fxrstor64 \(%r8\)
+[      ]*[a-f0-9]+:    49 0f ae 0c 00          fxrstor64 \(%r8,%rax,1\)
+[      ]*[a-f0-9]+:    4a 0f ae 0c 00          fxrstor64 \(%rax,%r8,1\)
+[      ]*[a-f0-9]+:    4b 0f ae 0c 38          fxrstor64 \(%r8,%r15,1\)
+[      ]*[a-f0-9]+:    0f ae 00                fxsave \(%rax\)
+[      ]*[a-f0-9]+:    41 0f ae 00             fxsave \(%r8\)
+[      ]*[a-f0-9]+:    41 0f ae 04 00          fxsave \(%r8,%rax,1\)
+[      ]*[a-f0-9]+:    42 0f ae 04 00          fxsave \(%rax,%r8,1\)
+[      ]*[a-f0-9]+:    43 0f ae 04 38          fxsave \(%r8,%r15,1\)
+[      ]*[a-f0-9]+:    48 0f ae 00             fxsave64 \(%rax\)
+[      ]*[a-f0-9]+:    49 0f ae 00             fxsave64 \(%r8\)
+[      ]*[a-f0-9]+:    49 0f ae 04 00          fxsave64 \(%r8,%rax,1\)
+[      ]*[a-f0-9]+:    4a 0f ae 04 00          fxsave64 \(%rax,%r8,1\)
+[      ]*[a-f0-9]+:    0f ae 08                fxrstor \(%rax\)
+[      ]*[a-f0-9]+:    41 0f ae 08             fxrstor \(%r8\)
+[      ]*[a-f0-9]+:    41 0f ae 0c 00          fxrstor \(%r8,%rax,1\)
+[      ]*[a-f0-9]+:    42 0f ae 0c 00          fxrstor \(%rax,%r8,1\)
+[      ]*[a-f0-9]+:    43 0f ae 0c 38          fxrstor \(%r8,%r15,1\)
+[      ]*[a-f0-9]+:    48 0f ae 08             fxrstor64 \(%rax\)
+[      ]*[a-f0-9]+:    49 0f ae 08             fxrstor64 \(%r8\)
+[      ]*[a-f0-9]+:    49 0f ae 0c 00          fxrstor64 \(%r8,%rax,1\)
+[      ]*[a-f0-9]+:    4a 0f ae 0c 00          fxrstor64 \(%rax,%r8,1\)
+[      ]*[a-f0-9]+:    4b 0f ae 0c 38          fxrstor64 \(%r8,%r15,1\)
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-fxsave.s b/gas/testsuite/gas/i386/x86-64-fxsave.s
new file mode 100644 (file)
index 0000000..c2b1862
--- /dev/null
@@ -0,0 +1,44 @@
+# Check 64bit fxsave/frstor instructions.
+
+       .text
+foo:
+       fxsave (%rax)
+       fxsave (%r8)
+       fxsave (%r8, %rax)
+       fxsave (%rax, %r8)
+       fxsave (%r8, %r15)
+       fxsave64 (%rax)
+       fxsave64 (%r8)
+       fxsave64 (%r8, %rax)
+       fxsave64 (%rax, %r8)
+       fxrstor (%rax)
+       fxrstor (%r8)
+       fxrstor (%r8, %rax)
+       fxrstor (%rax, %r8)
+       fxrstor (%r8, %r15)
+       fxrstor64 (%rax)
+       fxrstor64 (%r8)
+       fxrstor64 (%r8, %rax)
+       fxrstor64 (%rax, %r8)
+       fxrstor64 (%r8, %r15)
+
+       .intel_syntax noprefix
+fxsave [rax]
+fxsave [r8]
+fxsave [r8+rax*1]
+fxsave [rax+r8*1]
+fxsave [r8+r15*1]
+fxsave64 [rax]
+fxsave64 [r8]
+fxsave64 [r8+rax*1]
+fxsave64 [rax+r8*1]
+fxrstor [rax]
+fxrstor [r8]
+fxrstor [r8+rax*1]
+fxrstor [rax+r8*1]
+fxrstor [r8+r15*1]
+fxrstor64 [rax]
+fxrstor64 [r8]
+fxrstor64 [r8+rax*1]
+fxrstor64 [rax+r8*1]
+fxrstor64 [r8+r15*1]
index 4899711..7ecb512 100644 (file)
@@ -1,3 +1,12 @@
+2009-12-03  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * i386-dis.c (FXSAVE_Fixup): New.
+       (FXSAVE): Likewise.
+       (mod_table): Use FXSAVE on fxsave and fxrstor.
+
+       * i386-opc.tbl: Add fxsave64 and fxrstor64.
+       * i386-tbl.h: Regenerated.
+
 2009-12-02  Nick Clifton  <nickc@redhat.com>
            Richard Earnshaw  <rearnsha@arm.com>
 
index a9bb2b1..0e5b0ab 100644 (file)
@@ -110,6 +110,7 @@ static void REP_Fixup (int, int);
 static void CMPXCHG8B_Fixup (int, int);
 static void XMM_Fixup (int, int);
 static void CRC32_Fixup (int, int);
+static void FXSAVE_Fixup (int, int);
 static void OP_LWPCB_E (int, int);
 static void OP_LWP_E (int, int);
 static void OP_LWP_I (int, int);
@@ -358,6 +359,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define OPSUF { OP_3DNowSuffix, 0 }
 #define CMP { CMP_Fixup, 0 }
 #define XMM0 { XMM_Fixup, 0 }
+#define FXSAVE { FXSAVE_Fixup, 0 }
 #define Vex_2src_1 { OP_Vex_2src_1, 0 }
 #define Vex_2src_2 { OP_Vex_2src_2, 0 }
 
@@ -9541,12 +9543,12 @@ static const struct dis386 mod_table[][2] = {
   },
   {
     /* MOD_0FAE_REG_0 */
-    { "fxsave",                { M } },
+    { "fxsave",                { FXSAVE } },
     { "(bad)",         { XX } },
   },
   {
     /* MOD_0FAE_REG_1 */
-    { "fxrstor",       { M } },
+    { "fxrstor",       { FXSAVE } },
     { "(bad)",         { XX } },
   },
   {
@@ -13641,6 +13643,22 @@ skip:
     OP_E (bytemode, sizeflag);
 }
 
+static void
+FXSAVE_Fixup (int bytemode, int sizeflag)
+{
+  /* Add proper suffix to "fxsave" and "fxrstor".  */
+  USED_REX (REX_W);
+  if (rex & REX_W)
+    {
+      char *p = mnemonicendp;
+      *p++ = '6';
+      *p++ = '4';
+      *p = '\0';
+      mnemonicendp = p;
+    }
+  OP_M (bytemode, sizeflag);
+}
+
 /* Display the destination register operand for instructions with
    VEX. */
 
index 37dccab..3f8bcaa 100644 (file)
@@ -848,7 +848,9 @@ cmpxchg8b, 1, 0xfc7, 0x1, 2, Cpu586, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ld
 sysenter, 0, 0xf34, None, 2, Cpu686, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
 sysexit, 0, 0xf35, None, 2, Cpu686, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
 fxsave, 1, 0xfae, 0x0, 2, Cpu686, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf, { Unspecified|BaseIndex|Disp8|Disp16|Disp32|Disp32S }
+fxsave64, 1, 0xfae, 0x0, 2, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|Rex64, { Unspecified|BaseIndex|Disp8|Disp16|Disp32|Disp32S }
 fxrstor, 1, 0xfae, 0x1, 2, Cpu686, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf, { Unspecified|BaseIndex|Disp8|Disp16|Disp32|Disp32S }
+fxrstor64, 1, 0xfae, 0x1, 2, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|Rex64, { Unspecified|BaseIndex|Disp8|Disp16|Disp32|Disp32S }
 rdpmc, 0, 0xf33, None, 2, Cpu686, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
 // official undefined instr.
 ud2, 0, 0xf0b, None, 2, Cpu686, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
index 9f2f7fb..1e98a6d 100644 (file)
@@ -6902,6 +6902,16 @@ const insn_template i386_optab[] =
     { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 1, 0, 0 } } } },
+  { "fxsave64", 1, 0xfae, 0x0, 2,
+    { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+        0, 1, 0, 0 } },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
+      1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+         1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+         0, 0, 1, 0, 0 } } } },
   { "fxrstor", 1, 0xfae, 0x1, 2,
     { { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -6912,6 +6922,16 @@ const insn_template i386_optab[] =
     { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
          0, 0, 1, 0, 0 } } } },
+  { "fxrstor64", 1, 0xfae, 0x1, 2,
+    { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+        0, 1, 0, 0 } },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
+      1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+         1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+         0, 0, 1, 0, 0 } } } },
   { "rdpmc", 0, 0xf33, None, 2,
     { { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,