1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#if V8_TARGET_ARCH_X87
6
7#include "src/codegen.h"
8#include "src/ic/ic.h"
9#include "src/ic/stub-cache.h"
10
11namespace v8 {
12namespace internal {
13
14
15Condition CompareIC::ComputeCondition(Token::Value op) {
16  switch (op) {
17    case Token::EQ_STRICT:
18    case Token::EQ:
19      return equal;
20    case Token::LT:
21      return less;
22    case Token::GT:
23      return greater;
24    case Token::LTE:
25      return less_equal;
26    case Token::GTE:
27      return greater_equal;
28    default:
29      UNREACHABLE();
30      return no_condition;
31  }
32}
33
34
35bool CompareIC::HasInlinedSmiCode(Address address) {
36  // The address of the instruction following the call.
37  Address test_instruction_address =
38      address + Assembler::kCallTargetAddressOffset;
39
40  // If the instruction following the call is not a test al, nothing
41  // was inlined.
42  return *test_instruction_address == Assembler::kTestAlByte;
43}
44
45
46void PatchInlinedSmiCode(Isolate* isolate, Address address,
47                         InlinedSmiCheck check) {
48  // The address of the instruction following the call.
49  Address test_instruction_address =
50      address + Assembler::kCallTargetAddressOffset;
51
52  // If the instruction following the call is not a test al, nothing
53  // was inlined.
54  if (*test_instruction_address != Assembler::kTestAlByte) {
55    DCHECK(*test_instruction_address == Assembler::kNopByte);
56    return;
57  }
58
59  Address delta_address = test_instruction_address + 1;
60  // The delta to the start of the map check instruction and the
61  // condition code uses at the patched jump.
62  uint8_t delta = *reinterpret_cast<uint8_t*>(delta_address);
63  if (FLAG_trace_ic) {
64    LOG(isolate, PatchIC(address, test_instruction_address, delta));
65  }
66
67  // Patch with a short conditional jump. Enabling means switching from a short
68  // jump-if-carry/not-carry to jump-if-zero/not-zero, whereas disabling is the
69  // reverse operation of that.
70  Address jmp_address = test_instruction_address - delta;
71  DCHECK((check == ENABLE_INLINED_SMI_CHECK)
72             ? (*jmp_address == Assembler::kJncShortOpcode ||
73                *jmp_address == Assembler::kJcShortOpcode)
74             : (*jmp_address == Assembler::kJnzShortOpcode ||
75                *jmp_address == Assembler::kJzShortOpcode));
76  Condition cc =
77      (check == ENABLE_INLINED_SMI_CHECK)
78          ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
79          : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
80  *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
81}
82}  // namespace internal
83}  // namespace v8
84
85#endif  // V8_TARGET_ARCH_X87
86