~yolanda.robla/ubuntu/trusty/nodejs/add_distribution

« back to all changes in this revision

Viewing changes to deps/v8/src/ia32/disasm-ia32.cc

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2013-08-14 00:16:46 UTC
  • mfrom: (7.1.40 sid)
  • Revision ID: package-import@ubuntu.com-20130814001646-bzlysfh8sd6mukbo
Tags: 0.10.15~dfsg1-4
* Update 2005 patch, adding a handful of tests that can fail on
  slow platforms.
* Add 1004 patch to fix test failures when writing NaN to buffer
  on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
 
56
56
 
57
57
static const ByteMnemonic two_operands_instr[] = {
 
58
  {0x01, "add", OPER_REG_OP_ORDER},
58
59
  {0x03, "add", REG_OPER_OP_ORDER},
59
60
  {0x09, "or", OPER_REG_OP_ORDER},
60
61
  {0x0B, "or", REG_OPER_OP_ORDER},
117
118
};
118
119
 
119
120
 
 
121
// Generally we don't want to generate these because they are subject to partial
 
122
// register stalls.  They are included for completeness and because the cmp
 
123
// variant is used by the RecordWrite stub.  Because it does not update the
 
124
// register it is not subject to partial register stalls.
 
125
static ByteMnemonic byte_immediate_instr[] = {
 
126
  {0x0c, "or", UNSET_OP_ORDER},
 
127
  {0x24, "and", UNSET_OP_ORDER},
 
128
  {0x34, "xor", UNSET_OP_ORDER},
 
129
  {0x3c, "cmp", UNSET_OP_ORDER},
 
130
  {-1, "", UNSET_OP_ORDER}
 
131
};
 
132
 
 
133
 
120
134
static const char* const jump_conditional_mnem[] = {
121
135
  /*0*/ "jo", "jno", "jc", "jnc",
122
136
  /*4*/ "jz", "jnz", "jna", "ja",
149
163
  REGISTER_INSTR,
150
164
  MOVE_REG_INSTR,
151
165
  CALL_JUMP_INSTR,
152
 
  SHORT_IMMEDIATE_INSTR
 
166
  SHORT_IMMEDIATE_INSTR,
 
167
  BYTE_IMMEDIATE_INSTR
153
168
};
154
169
 
155
170
 
164
179
 public:
165
180
  InstructionTable();
166
181
  const InstructionDesc& Get(byte x) const { return instructions_[x]; }
 
182
  static InstructionTable* get_instance() {
 
183
    static InstructionTable table;
 
184
    return &table;
 
185
  }
167
186
 
168
187
 private:
169
188
  InstructionDesc instructions_[256];
198
217
  CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR);
199
218
  CopyTable(call_jump_instr, CALL_JUMP_INSTR);
200
219
  CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
 
220
  CopyTable(byte_immediate_instr, BYTE_IMMEDIATE_INSTR);
201
221
  AddJumpConditionalShort();
202
222
  SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc");
203
223
  SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec");
243
263
}
244
264
 
245
265
 
246
 
static InstructionTable instruction_table;
247
 
 
248
 
 
249
266
// The IA32 disassembler implementation.
250
267
class DisassemblerIA32 {
251
268
 public:
252
269
  DisassemblerIA32(const NameConverter& converter,
253
270
                   bool abort_on_unimplemented = true)
254
271
      : converter_(converter),
 
272
        instruction_table_(InstructionTable::get_instance()),
255
273
        tmp_buffer_pos_(0),
256
274
        abort_on_unimplemented_(abort_on_unimplemented) {
257
275
    tmp_buffer_[0] = '\0';
265
283
 
266
284
 private:
267
285
  const NameConverter& converter_;
 
286
  InstructionTable* instruction_table_;
268
287
  v8::internal::EmbeddedVector<char, 128> tmp_buffer_;
269
288
  unsigned int tmp_buffer_pos_;
270
289
  bool abort_on_unimplemented_;
271
290
 
272
 
 
273
291
  enum {
274
292
    eax = 0,
275
293
    ecx = 1,
535
553
      case 2: mnem = "not"; break;
536
554
      case 3: mnem = "neg"; break;
537
555
      case 4: mnem = "mul"; break;
 
556
      case 5: mnem = "imul"; break;
538
557
      case 7: mnem = "idiv"; break;
539
558
      default: UnimplementedInstruction();
540
559
    }
745
764
            case 0xEB: mnem = "fldpi"; break;
746
765
            case 0xED: mnem = "fldln2"; break;
747
766
            case 0xEE: mnem = "fldz"; break;
 
767
            case 0xF0: mnem = "f2xm1"; break;
748
768
            case 0xF1: mnem = "fyl2x"; break;
749
769
            case 0xF5: mnem = "fprem1"; break;
750
770
            case 0xF7: mnem = "fincstp"; break;
751
771
            case 0xF8: mnem = "fprem"; break;
 
772
            case 0xFC: mnem = "frndint"; break;
 
773
            case 0xFD: mnem = "fscale"; break;
752
774
            case 0xFE: mnem = "fsin"; break;
753
775
            case 0xFF: mnem = "fcos"; break;
754
776
            default: UnimplementedInstruction();
770
792
        has_register = true;
771
793
      } else if (modrm_byte  == 0xE2) {
772
794
        mnem = "fclex";
 
795
      } else if (modrm_byte == 0xE3) {
 
796
        mnem = "fninit";
773
797
      } else {
774
798
        UnimplementedInstruction();
775
799
      }
868
892
  }
869
893
  bool processed = true;  // Will be set to false if the current instruction
870
894
                          // is not in 'instructions' table.
871
 
  const InstructionDesc& idesc = instruction_table.Get(*data);
 
895
  const InstructionDesc& idesc = instruction_table_->Get(*data);
872
896
  switch (idesc.type) {
873
897
    case ZERO_OPERANDS_INSTR:
874
898
      AppendToBuffer(idesc.mnem);
912
936
      break;
913
937
    }
914
938
 
 
939
    case BYTE_IMMEDIATE_INSTR: {
 
940
      AppendToBuffer("%s al, 0x%x", idesc.mnem, data[1]);
 
941
      data += 2;
 
942
      break;
 
943
    }
 
944
 
915
945
    case NO_INSTR:
916
946
      processed = false;
917
947
      break;
963
993
        break;
964
994
 
965
995
      case 0x0F:
966
 
        { byte f0byte = *(data+1);
 
996
        { byte f0byte = data[1];
967
997
          const char* f0mnem = F0Mnem(f0byte);
968
998
          if (f0byte == 0x18) {
969
999
            int mod, regop, rm;
971
1001
            const char* suffix[] = {"nta", "1", "2", "3"};
972
1002
            AppendToBuffer("%s%s ", f0mnem, suffix[regop & 0x03]);
973
1003
            data += PrintRightOperand(data);
 
1004
          } else if (f0byte == 0x1F && data[2] == 0) {
 
1005
            AppendToBuffer("nop");  // 3 byte nop.
 
1006
            data += 3;
 
1007
          } else if (f0byte == 0x1F && data[2] == 0x40 && data[3] == 0) {
 
1008
            AppendToBuffer("nop");  // 4 byte nop.
 
1009
            data += 4;
 
1010
          } else if (f0byte == 0x1F && data[2] == 0x44 && data[3] == 0 &&
 
1011
                     data[4] == 0) {
 
1012
            AppendToBuffer("nop");  // 5 byte nop.
 
1013
            data += 5;
 
1014
          } else if (f0byte == 0x1F && data[2] == 0x80 && data[3] == 0 &&
 
1015
                     data[4] == 0 && data[5] == 0 && data[6] == 0) {
 
1016
            AppendToBuffer("nop");  // 7 byte nop.
 
1017
            data += 7;
 
1018
          } else if (f0byte == 0x1F && data[2] == 0x84 && data[3] == 0 &&
 
1019
                     data[4] == 0 && data[5] == 0 && data[6] == 0 &&
 
1020
                     data[7] == 0) {
 
1021
            AppendToBuffer("nop");  // 8 byte nop.
 
1022
            data += 8;
974
1023
          } else if (f0byte == 0xA2 || f0byte == 0x31) {
975
1024
            AppendToBuffer("%s", f0mnem);
976
1025
            data += 2;
1106
1155
        break;
1107
1156
 
1108
1157
      case 0x66:  // prefix
1109
 
        data++;
1110
 
        if (*data == 0x8B) {
 
1158
        while (*data == 0x66) data++;
 
1159
        if (*data == 0xf && data[1] == 0x1f) {
 
1160
          AppendToBuffer("nop");  // 0x66 prefix
 
1161
        } else if (*data == 0x90) {
 
1162
          AppendToBuffer("nop");  // 0x66 prefix
 
1163
        } else if (*data == 0x8B) {
1111
1164
          data++;
1112
1165
          data += PrintOperands("mov_w", REG_OPER_OP_ORDER, data);
1113
1166
        } else if (*data == 0x89) {
1161
1214
                             NameOfXMMRegister(rm),
1162
1215
                             static_cast<int>(imm8));
1163
1216
              data += 2;
 
1217
            } else if (*data == 0x17) {
 
1218
              data++;
 
1219
              int mod, regop, rm;
 
1220
              get_modrm(*data, &mod, &regop, &rm);
 
1221
              int8_t imm8 = static_cast<int8_t>(data[1]);
 
1222
              AppendToBuffer("extractps %s,%s,%d",
 
1223
                             NameOfCPURegister(regop),
 
1224
                             NameOfXMMRegister(rm),
 
1225
                             static_cast<int>(imm8));
 
1226
              data += 2;
1164
1227
            } else if (*data == 0x22) {
1165
1228
              data++;
1166
1229
              int mod, regop, rm;
1204
1267
                           NameOfXMMRegister(regop),
1205
1268
                           NameOfXMMRegister(rm));
1206
1269
            data++;
 
1270
          } else if (*data == 0x56) {
 
1271
            data++;
 
1272
            int mod, regop, rm;
 
1273
            get_modrm(*data, &mod, &regop, &rm);
 
1274
            AppendToBuffer("orpd %s,%s",
 
1275
                           NameOfXMMRegister(regop),
 
1276
                           NameOfXMMRegister(rm));
 
1277
            data++;
1207
1278
          } else if (*data == 0x57) {
1208
1279
            data++;
1209
1280
            int mod, regop, rm;
1234
1305
                           NameOfXMMRegister(rm),
1235
1306
                           static_cast<int>(imm8));
1236
1307
            data += 2;
 
1308
          } else if (*data == 0x76) {
 
1309
            data++;
 
1310
            int mod, regop, rm;
 
1311
            get_modrm(*data, &mod, &regop, &rm);
 
1312
            AppendToBuffer("pcmpeqd %s,%s",
 
1313
                           NameOfXMMRegister(regop),
 
1314
                           NameOfXMMRegister(rm));
 
1315
            data++;
 
1316
          } else if (*data == 0x90) {
 
1317
            data++;
 
1318
            AppendToBuffer("nop");  // 2 byte nop.
1237
1319
          } else if (*data == 0xF3) {
1238
1320
            data++;
1239
1321
            int mod, regop, rm;
1346
1428
        data += 2;
1347
1429
        break;
1348
1430
 
1349
 
      case 0x2C:
1350
 
        AppendToBuffer("subb eax,0x%x", *reinterpret_cast<uint8_t*>(data+1));
1351
 
        data += 2;
1352
 
        break;
1353
 
 
1354
1431
      case 0xA9:
1355
1432
        AppendToBuffer("test eax,0x%x", *reinterpret_cast<int32_t*>(data+1));
1356
1433
        data += 5;
1403
1480
            switch (b2) {
1404
1481
              case 0x2A: mnem = "cvtsi2sd"; break;
1405
1482
              case 0x2C: mnem = "cvttsd2si"; break;
 
1483
              case 0x2D: mnem = "cvtsd2si"; break;
1406
1484
              case 0x51: mnem = "sqrtsd"; break;
1407
1485
              case 0x58: mnem = "addsd"; break;
1408
1486
              case 0x59: mnem = "mulsd"; break;
1415
1493
            if (b2 == 0x2A) {
1416
1494
              AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop));
1417
1495
              data += PrintRightOperand(data);
1418
 
            } else if (b2 == 0x2C) {
 
1496
            } else if (b2 == 0x2C || b2 == 0x2D) {
1419
1497
              AppendToBuffer("%s %s,", mnem, NameOfCPURegister(regop));
1420
1498
              data += PrintRightXMMOperand(data);
1421
1499
            } else if (b2 == 0xC2) {