x86 validator: Implement rewriting "movntq" to "movq" on x86-64

We were already doing this rewrite for x86-32.

We had previously checked the Web Store to find all the non-temporal
instructions that we need to handle and rewrite, but it looks like we
missed at least one -- "movntq" is being used.  The use might have
appeared after we did the check.

BUG= https://bugs.chromium.org/p/chromium/issues/detail?id=598085
TEST=run_validation_rewrite_test run_rewrite_nontemporals_test run_validation_cache_test

Review URL: https://codereview.chromium.org/1836633002

(cherry picked from commit fb2c685d12b5a13cdb5b284b0ee1ee3c2080a769)

Review URL: https://codereview.chromium.org/1863433002
diff --git a/src/trusted/validator/validation_rewrite_test.cc b/src/trusted/validator/validation_rewrite_test.cc
index e1d1bac..a392f69 100644
--- a/src/trusted/validator/validation_rewrite_test.cc
+++ b/src/trusted/validator/validation_rewrite_test.cc
@@ -44,6 +44,7 @@
 DECLARE_TEMPLATE(off_webstore_movnt_code)
 DECLARE_TEMPLATE(prefetchnta_code)
 DECLARE_TEMPLATE(prefetchnta_rip_relative_code)
+DECLARE_TEMPLATE(movntq_code)
 DECLARE_TEMPLATE(movntps_code)
 DECLARE_TEMPLATE(movnti_code)
 DECLARE_TEMPLATE(movnti_code2)
@@ -138,6 +139,10 @@
   TestRewrite(&t_prefetchnta_rip_relative_code);
 }
 
+TEST_F(ValidationMovntRewriteTests, RewriteMovntq) {
+  TestRewrite(&t_movntq_code);
+}
+
 TEST_F(ValidationMovntRewriteTests, RewriteMovntps) {
   TestRewrite(&t_movntps_code);
 }
diff --git a/src/trusted/validator/validation_rewrite_test_data.S b/src/trusted/validator/validation_rewrite_test_data.S
index 0f167c8..41d065d 100644
--- a/src/trusted/validator/validation_rewrite_test_data.S
+++ b/src/trusted/validator/validation_rewrite_test_data.S
@@ -99,6 +99,16 @@
     nop
 GLOBAL_SYM(prefetchnta_rip_relative_code_post_rewrite_end)
 
+GLOBAL_SYM(movntq_code)
+    mov %ebx,%ebx
+    movntq %mm0,(%r15,%rbx,1)
+GLOBAL_SYM(movntq_code_end)
+
+GLOBAL_SYM(movntq_code_post_rewrite)
+    mov %ebx,%ebx
+    movq %mm0,(%r15,%rbx,1)
+GLOBAL_SYM(movntq_code_post_rewrite_end)
+
 GLOBAL_SYM(movntps_code)
     mov %ebx,%ebx
     movntps %xmm0,(%r15,%rbx,1)
diff --git a/src/trusted/validator_ragel/dfa_validate_common.c b/src/trusted/validator_ragel/dfa_validate_common.c
index 7bb63a5..7eb4465 100644
--- a/src/trusted/validator_ragel/dfa_validate_common.c
+++ b/src/trusted/validator_ragel/dfa_validate_common.c
@@ -92,6 +92,10 @@
   if (size >= 3 && IsREXPrefix(ptr[0]) && ptr[1] == 0x0f) {
     uint8_t opcode_byte2 = ptr[2];
     switch (opcode_byte2) {
+      case 0xe7:
+        /* movntq => movq */
+        ptr[2] = 0x7f;
+        return TRUE;
       case 0x2b:
         /* movntps => movaps */
         ptr[2] = 0x29;
diff --git a/tests/validator/rewrite_nontemporals.c b/tests/validator/rewrite_nontemporals.c
index 00a8679..cbed4b2 100644
--- a/tests/validator/rewrite_nontemporals.c
+++ b/tests/validator/rewrite_nontemporals.c
@@ -40,13 +40,11 @@
   /* This compiles to prefetchnta on x86. */
   __builtin_prefetch(&g_dest, /* rw= */ 0, /* locality= */ 0);
 
-#if defined(__i386__)
   /* Test movntq. */
   reset_test_vars();
-  asm("movq g_src, %%mm0\n"
-      "movntq %%mm0, g_dest\n" : : : "mm0");
+  asm("movq g_src" MEM_SUFFIX ", %%mm0\n"
+      "movntq %%mm0, g_dest" MEM_SUFFIX "\n" : : : "mm0");
   ASSERT_EQ(memcmp(g_dest, g_src, 8), 0);
-#endif
 
 #if defined(__x86_64__)
   /* Test movntps. */