about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-09-30 23:12:39 -0700
committerKartik Agaram <vc@akkartik.com>2020-09-30 23:12:39 -0700
commit6453bbbff881203691a2baf10066ed491d5c6928 (patch)
treeef24e61572cb519ac04be21ad6b64a06589dd7c5
parentd44bd51f9006a2a5a6328e812be0e11a4cef548f (diff)
downloadmu-6453bbbff881203691a2baf10066ed491d5c6928.tar.gz
6913 - copying floats around
-rw-r--r--023float.cc75
-rw-r--r--033check_operands.cc2
2 files changed, 77 insertions, 0 deletions
diff --git a/023float.cc b/023float.cc
index 324ab934..e3524c98 100644
--- a/023float.cc
+++ b/023float.cc
@@ -1,5 +1,80 @@
 //: floating-point operations
 
+//:: copy
+
+:(before "End Initialize Op Names")
+put_new(Name_f3_0f, "10", "copy xm32 to x32 (movss)");
+put_new(Name_f3_0f, "11", "copy x32 to xm32 (movss)");
+
+:(code)
+void test_copy_x32_to_x32() {
+  Xmm[3] = 0.5;
+  run(
+      "== code 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "f3 0f 11 d8                                    \n"  // copy XMM3 to XMM0
+      // ModR/M in binary: 11 (direct mode) 011 (src XMM3) 000 (dest XMM0)
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: copy XMM3 to x/m32\n"
+      "run: x/m32 is XMM0\n"
+      "run: storing 0.5\n"
+  );
+}
+
+:(before "End Three-Byte Opcodes Starting With f3 0f")
+case 0x10: {  // copy x/m32 to x32
+  const uint8_t modrm = next();
+  const uint8_t rdest = (modrm>>3)&0x7;
+  trace(Callstack_depth+1, "run") << "copy x/m32 to " << Xname[rdest] << end();
+  float* src = effective_address_float(modrm);
+  Xmm[rdest] = *src;  // Write multiple elements of vector<uint8_t> at once. Assumes sizeof(float) == 4 on the host as well.
+  trace(Callstack_depth+1, "run") << "storing " << Xmm[rdest] << end();
+  break;
+}
+case 0x11: {  // copy x32 to x/m32
+  const uint8_t modrm = next();
+  const uint8_t rsrc = (modrm>>3)&0x7;
+  trace(Callstack_depth+1, "run") << "copy " << Xname[rsrc] << " to x/m32" << end();
+  float* dest = effective_address_float(modrm);
+  *dest = Xmm[rsrc];  // Write multiple elements of vector<uint8_t> at once. Assumes sizeof(float) == 4 on the host as well.
+  trace(Callstack_depth+1, "run") << "storing " << *dest << end();
+  break;
+}
+
+:(code)
+void test_copy_x32_to_mem_at_xm32() {
+  Xmm[3] = 0.5;
+  Reg[EAX].i = 0x60;
+  run(
+      "== code 0x1\n"
+      // op     ModR/M  SIB   displacement  immediate
+      "f3 0f 11 18                                    \n"  // copy XMM3 to *EAX
+      // ModR/M in binary: 00 (indirect mode) 011 (src XMM3) 000 (dest EAX)
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: copy XMM3 to x/m32\n"
+      "run: effective address is 0x00000060 (EAX)\n"
+      "run: storing 0.5\n"
+  );
+}
+
+void test_copy_mem_at_xm32_to_x32() {
+  Reg[EAX].i = 0x2000;
+  run(
+      "== code 0x1\n"
+      // op     ModR/M  SIB   displacement  immediate
+      "f3 0f 10 18                                    \n"  // copy *EAX to XMM3
+      "== data 0x2000\n"
+      "00 00 00 3f\n"  // 0x3f000000 = 0.5
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: copy x/m32 to XMM3\n"
+      "run: effective address is 0x00002000 (EAX)\n"
+      "run: storing 0.5\n"
+  );
+}
+
 //:: convert to floating point
 
 :(before "End Initialize Op Names")
diff --git a/033check_operands.cc b/033check_operands.cc
index 7089bbb2..08341aa6 100644
--- a/033check_operands.cc
+++ b/033check_operands.cc
@@ -698,6 +698,8 @@ map</*op*/string, /*bitvector*/uint8_t> Permitted_arguments_f3_0f;
 //// Class M: using ModR/M byte
 //  imm32 imm8  disp32 |disp16  disp8 subop modrm
 //  0     0     0      |0       0     0     1
+put_new(Permitted_arguments_f3_0f, "10", 0x01);  // copy xm32 to x32
+put_new(Permitted_arguments_f3_0f, "11", 0x01);  // copy x32 to xm32
 put_new(Permitted_arguments_f3_0f, "2a", 0x01);  // convert-to-float
 put_new(Permitted_arguments_f3_0f, "2d", 0x01);  // convert-to-int
 put_new(Permitted_arguments_f3_0f, "51", 0x01);  // square root