if (access.IsExternalMemory()) {
Register result = ToRegister(instr->result());
MemOperand operand = MemOperand(object, offset);
- if (access.representation().IsByte()) {
- __ ldrb(result, operand);
- } else {
- __ ldr(result, operand);
- }
+ __ Load(result, operand, access.representation());
return;
}
object = result;
}
MemOperand operand = FieldMemOperand(object, offset);
- if (access.representation().IsByte()) {
- __ ldrb(result, operand);
- } else {
- __ ldr(result, operand);
- }
+ __ Load(result, operand, access.representation());
}
if (access.IsExternalMemory()) {
Register value = ToRegister(instr->value());
MemOperand operand = MemOperand(object, offset);
- if (representation.IsByte()) {
- __ strb(value, operand);
- } else {
- __ str(value, operand);
- }
+ __ Store(value, operand, representation);
return;
}
? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
if (access.IsInobject()) {
MemOperand operand = FieldMemOperand(object, offset);
- if (representation.IsByte()) {
- __ strb(value, operand);
- } else {
- __ str(value, operand);
- }
+ __ Store(value, operand, representation);
if (instr->hydrogen()->NeedsWriteBarrier()) {
// Update the write barrier for the object for in-object properties.
__ RecordWriteField(object,
} else {
__ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset));
MemOperand operand = FieldMemOperand(scratch, offset);
- if (representation.IsByte()) {
- __ strb(value, operand);
- } else {
- __ str(value, operand);
- }
+ __ Store(value, operand, representation);
if (instr->hydrogen()->NeedsWriteBarrier()) {
// Update the write barrier for the properties array.
// object is used as a scratch register.
}
+void MacroAssembler::Load(Register dst,
+ const MemOperand& src,
+ Representation r) {
+ ASSERT(!r.IsDouble());
+ if (r.IsInteger8()) {
+ ldrsb(dst, src);
+ } else if (r.IsUInteger8()) {
+ ldrb(dst, src);
+ } else if (r.IsInteger16()) {
+ ldrsh(dst, src);
+ } else if (r.IsUInteger16()) {
+ ldrh(dst, src);
+ } else {
+ ldr(dst, src);
+ }
+}
+
+
+void MacroAssembler::Store(Register src,
+ const MemOperand& dst,
+ Representation r) {
+ ASSERT(!r.IsDouble());
+ if (r.IsInteger8() || r.IsUInteger8()) {
+ strb(src, dst);
+ } else if (r.IsInteger16() || r.IsUInteger16()) {
+ strh(src, dst);
+ } else {
+ str(src, dst);
+ }
+}
+
+
void MacroAssembler::LoadRoot(Register destination,
Heap::RootListIndex index,
Condition cond) {
void Move(Register dst, Register src, Condition cond = al);
void Move(DwVfpRegister dst, DwVfpRegister src);
+ void Load(Register dst, const MemOperand& src, Representation r);
+ void Store(Register src, const MemOperand& dst, Representation r);
+
// Load an object from the root table.
void LoadRoot(Register destination,
Heap::RootListIndex index,
const int GB = KB * KB * KB;
const int kMaxInt = 0x7FFFFFFF;
const int kMinInt = -kMaxInt - 1;
+const int kMaxInt8 = (1 << 7) - 1;
+const int kMinInt8 = -(1 << 7);
+const int kMaxUInt8 = (1 << 8) - 1;
+const int kMinUInt8 = 0;
+const int kMaxInt16 = (1 << 15) - 1;
+const int kMinInt16 = -(1 << 15);
+const int kMaxUInt16 = (1 << 16) - 1;
+const int kMinUInt16 = 0;
const uint32_t kMaxUInt32 = 0xFFFFFFFFu;
Range* HLoadNamedField::InferRange(Zone* zone) {
- if (access().representation().IsByte()) {
- return new(zone) Range(0, 255);
+ if (access().representation().IsInteger8()) {
+ return new(zone) Range(kMinInt8, kMaxInt8);
+ }
+ if (access().representation().IsUInteger8()) {
+ return new(zone) Range(kMinUInt8, kMaxUInt8);
+ }
+ if (access().representation().IsInteger16()) {
+ return new(zone) Range(kMinInt16, kMaxInt16);
+ }
+ if (access().representation().IsUInteger16()) {
+ return new(zone) Range(kMinUInt16, kMaxUInt16);
}
if (access().IsStringLength()) {
return new(zone) Range(0, String::kMaxLength);
Range* HLoadKeyed::InferRange(Zone* zone) {
switch (elements_kind()) {
- case EXTERNAL_PIXEL_ELEMENTS:
- return new(zone) Range(0, 255);
case EXTERNAL_BYTE_ELEMENTS:
- return new(zone) Range(-128, 127);
+ return new(zone) Range(kMinInt8, kMaxInt8);
case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
- return new(zone) Range(0, 255);
+ case EXTERNAL_PIXEL_ELEMENTS:
+ return new(zone) Range(kMinUInt8, kMaxUInt8);
case EXTERNAL_SHORT_ELEMENTS:
- return new(zone) Range(-32768, 32767);
+ return new(zone) Range(kMinInt16, kMaxInt16);
case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
- return new(zone) Range(0, 65535);
+ return new(zone) Range(kMinUInt16, kMaxUInt16);
default:
return HValue::InferRange(zone);
}
static HObjectAccess ForMapInstanceSize() {
return HObjectAccess(kInobject,
Map::kInstanceSizeOffset,
- Representation::Byte());
+ Representation::UInteger8());
}
static HObjectAccess ForPropertyCellValue() {
}
class PortionField : public BitField<Portion, 0, 3> {};
- class RepresentationField : public BitField<Representation::Kind, 3, 3> {};
- class OffsetField : public BitField<int, 6, 26> {};
+ class RepresentationField : public BitField<Representation::Kind, 3, 4> {};
+ class OffsetField : public BitField<int, 7, 25> {};
uint32_t value_; // encodes portion, representation, and offset
Handle<String> name_;
SetOperandAt(0, object);
Representation representation = access.representation();
- if (representation.IsByte()) {
+ if (representation.IsInteger8() ||
+ representation.IsUInteger8() ||
+ representation.IsInteger16() ||
+ representation.IsUInteger16()) {
set_representation(Representation::Integer32());
} else if (representation.IsSmi()) {
set_type(HType::Smi());
// object must be external in case of external memory access
return Representation::External();
} else if (index == 1) {
- if (field_representation().IsByte() ||
+ if (field_representation().IsInteger8() ||
+ field_representation().IsUInteger8() ||
+ field_representation().IsInteger16() ||
+ field_representation().IsUInteger16() ||
field_representation().IsInteger32()) {
return Representation::Integer32();
} else if (field_representation().IsDouble() ||
KillFieldInternal(object, field, NULL);
// Kill the next field in case of overlap.
- int size = kPointerSize;
- if (access.representation().IsByte()) size = 1;
- else if (access.representation().IsInteger32()) size = 4;
+ int size = access.representation().size();
int next_field = (offset + size - 1) / kPointerSize;
if (next_field != field) KillFieldInternal(object, next_field, NULL);
}
? MemOperand::StaticVariable(ToExternalReference(
LConstantOperand::cast(instr->object())))
: MemOperand(ToRegister(instr->object()), offset);
- if (access.representation().IsByte()) {
- ASSERT(instr->hydrogen()->representation().IsInteger32());
- __ movzx_b(result, operand);
- } else {
- __ mov(result, operand);
- }
+ __ Load(result, operand, access.representation());
return;
}
__ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
object = result;
}
- if (access.representation().IsByte()) {
- ASSERT(instr->hydrogen()->representation().IsInteger32());
- __ movzx_b(result, FieldOperand(object, offset));
- } else {
- __ mov(result, FieldOperand(object, offset));
- }
+ __ Load(result, FieldOperand(object, offset), access.representation());
}
ToExternalReference(LConstantOperand::cast(instr->object())))
: MemOperand(ToRegister(instr->object()), offset);
if (instr->value()->IsConstantOperand()) {
- ASSERT(!representation.IsByte());
LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
__ mov(operand, Immediate(ToInteger32(operand_value)));
} else {
Register value = ToRegister(instr->value());
- if (representation.IsByte()) {
- __ mov_b(operand, value);
- } else {
- __ mov(operand, value);
- }
+ __ Store(value, operand, representation);
}
return;
}
LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
if (operand_value->IsRegister()) {
Register value = ToRegister(operand_value);
- if (representation.IsByte()) {
- __ mov_b(operand, value);
- } else {
- __ mov(operand, value);
- }
+ __ Store(value, operand, representation);
} else {
Handle<Object> handle_value = ToHandle(operand_value);
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
}
} else {
Register value = ToRegister(instr->value());
- if (representation.IsByte()) {
- __ mov_b(operand, value);
- } else {
- __ mov(operand, value);
- }
+ __ Store(value, operand, representation);
}
if (instr->hydrogen()->NeedsWriteBarrier()) {
!(FLAG_track_double_fields && instr->field_representation().IsDouble());
LOperand* val;
- if (instr->field_representation().IsByte()) {
+ if (instr->field_representation().IsInteger8() ||
+ instr->field_representation().IsUInteger8()) {
// mov_b requires a byte register (i.e. any of eax, ebx, ecx, edx).
// Just force the value to be in eax and we're safe here.
val = UseFixed(instr->value(), eax);
}
+void MacroAssembler::Load(Register dst, const Operand& src, Representation r) {
+ ASSERT(!r.IsDouble());
+ if (r.IsInteger8()) {
+ movsx_b(dst, src);
+ } else if (r.IsUInteger8()) {
+ movzx_b(dst, src);
+ } else if (r.IsInteger16()) {
+ movsx_w(dst, src);
+ } else if (r.IsUInteger16()) {
+ movzx_w(dst, src);
+ } else {
+ mov(dst, src);
+ }
+}
+
+
+void MacroAssembler::Store(Register src, const Operand& dst, Representation r) {
+ ASSERT(!r.IsDouble());
+ if (r.IsInteger8() || r.IsUInteger8()) {
+ mov_b(dst, src);
+ } else if (r.IsInteger16() || r.IsUInteger16()) {
+ mov_w(dst, src);
+ } else {
+ mov(dst, src);
+ }
+}
+
+
void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
if (isolate()->heap()->RootCanBeTreatedAsConstant(index)) {
Handle<Object> value(&isolate()->heap()->roots_array_start()[index]);
// macro assembler.
MacroAssembler(Isolate* isolate, void* buffer, int size);
+ void Load(Register dst, const Operand& src, Representation r);
+ void Store(Register src, const Operand& dst, Representation r);
+
// Operations on roots in the root-array.
void LoadRoot(Register destination, Heap::RootListIndex index);
void StoreRoot(Register source, Register scratch, Heap::RootListIndex index);
public:
enum Kind {
kNone,
- kByte,
+ kInteger8,
+ kUInteger8,
+ kInteger16,
+ kUInteger16,
kSmi,
kInteger32,
kDouble,
static Representation None() { return Representation(kNone); }
static Representation Tagged() { return Representation(kTagged); }
- static Representation Byte() { return Representation(kByte); }
+ static Representation Integer8() { return Representation(kInteger8); }
+ static Representation UInteger8() { return Representation(kUInteger8); }
+ static Representation Integer16() { return Representation(kInteger16); }
+ static Representation UInteger16() {
+ return Representation(kUInteger16);
+ }
static Representation Smi() { return Representation(kSmi); }
static Representation Integer32() { return Representation(kInteger32); }
static Representation Double() { return Representation(kDouble); }
ASSERT(kind_ != kExternal);
ASSERT(other.kind_ != kExternal);
if (IsHeapObject()) return other.IsDouble() || other.IsNone();
+ if (kind_ == kUInteger8 && other.kind_ == kInteger8) return false;
+ if (kind_ == kUInteger16 && other.kind_ == kInteger16) return false;
return kind_ > other.kind_;
}
return Representation::Tagged();
}
+ int size() const {
+ ASSERT(!IsNone());
+ if (IsInteger8() || IsUInteger8()) {
+ return sizeof(uint8_t);
+ }
+ if (IsInteger16() || IsUInteger16()) {
+ return sizeof(uint16_t);
+ }
+ if (IsInteger32()) {
+ return sizeof(uint32_t);
+ }
+ return kPointerSize;
+ }
+
Kind kind() const { return static_cast<Kind>(kind_); }
bool IsNone() const { return kind_ == kNone; }
- bool IsByte() const { return kind_ == kByte; }
+ bool IsInteger8() const { return kind_ == kInteger8; }
+ bool IsUInteger8() const { return kind_ == kUInteger8; }
+ bool IsInteger16() const { return kind_ == kInteger16; }
+ bool IsUInteger16() const { return kind_ == kUInteger16; }
bool IsTagged() const { return kind_ == kTagged; }
bool IsSmi() const { return kind_ == kSmi; }
bool IsSmiOrTagged() const { return IsSmi() || IsTagged(); }
bool IsHeapObject() const { return kind_ == kHeapObject; }
bool IsExternal() const { return kind_ == kExternal; }
bool IsSpecialization() const {
- return IsByte() || IsSmi() || IsInteger32() || IsDouble();
+ return IsInteger8() || IsUInteger8() ||
+ IsInteger16() || IsUInteger16() ||
+ IsSmi() || IsInteger32() || IsDouble();
}
const char* Mnemonic() const;
// Bit fields for fast objects.
class DescriptorPointer: public BitField<uint32_t, 6, 11> {};
- class RepresentationField: public BitField<uint32_t, 17, 3> {};
- class FieldIndexField: public BitField<uint32_t, 20, 11> {};
+ class RepresentationField: public BitField<uint32_t, 17, 4> {};
+ class FieldIndexField: public BitField<uint32_t, 21, 10> {};
static const int kInitialIndex = 1;
void MacroAssembler::Load(Register dst, const Operand& src, Representation r) {
ASSERT(!r.IsDouble());
- if (r.IsByte()) {
+ if (r.IsInteger8()) {
+ movsxbq(dst, src);
+ } else if (r.IsUInteger8()) {
movzxbl(dst, src);
+ } else if (r.IsInteger16()) {
+ movsxwq(dst, src);
+ } else if (r.IsUInteger16()) {
+ movzxwl(dst, src);
} else if (r.IsInteger32()) {
movl(dst, src);
} else {
void MacroAssembler::Store(const Operand& dst, Register src, Representation r) {
ASSERT(!r.IsDouble());
- if (r.IsByte()) {
+ if (r.IsInteger8() || r.IsUInteger8()) {
movb(dst, src);
+ } else if (r.IsInteger16() || r.IsUInteger16()) {
+ movw(dst, src);
} else if (r.IsInteger32()) {
movl(dst, src);
} else {
'test-random-number-generator.cc',
'test-regexp.cc',
'test-reloc-info.cc',
+ 'test-representation.cc',
'test-semaphore.cc',
'test-serialize.cc',
'test-socket.cc',
'test-code-stubs-ia32.cc',
'test-cpu-ia32.cc',
'test-disasm-ia32.cc',
+ 'test-macro-assembler-ia32.cc',
'test-log-stack-tracer.cc'
],
}],
}
+typedef int (*F0)();
+
+
+TEST(LoadAndStoreWithRepresentation) {
+ v8::internal::V8::Initialize(NULL);
+
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
+ &actual_size,
+ true));
+ CHECK(buffer);
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope handles(isolate);
+ MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size));
+ MacroAssembler* masm = &assembler; // Create a pointer for the __ macro.
+ masm->set_allow_stub_calls(false);
+ __ sub(sp, sp, Operand(1 * kPointerSize));
+ Label exit;
+
+ // Test 1.
+ __ mov(r0, Operand(1)); // Test number.
+ __ mov(r1, Operand(0));
+ __ str(r1, MemOperand(sp, 0 * kPointerSize));
+ __ mov(r2, Operand(-1));
+ __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::UInteger8());
+ __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
+ __ mov(r2, Operand(255));
+ __ cmp(r3, r2);
+ __ b(ne, &exit);
+ __ mov(r2, Operand(255));
+ __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::UInteger8());
+ __ cmp(r3, r2);
+ __ b(ne, &exit);
+
+ // Test 2.
+ __ mov(r0, Operand(2)); // Test number.
+ __ mov(r1, Operand(0));
+ __ str(r1, MemOperand(sp, 0 * kPointerSize));
+ __ mov(r2, Operand(-1));
+ __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::Integer8());
+ __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
+ __ mov(r2, Operand(255));
+ __ cmp(r3, r2);
+ __ b(ne, &exit);
+ __ mov(r2, Operand(-1));
+ __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::Integer8());
+ __ cmp(r3, r2);
+ __ b(ne, &exit);
+
+ // Test 3.
+ __ mov(r0, Operand(3)); // Test number.
+ __ mov(r1, Operand(0));
+ __ str(r1, MemOperand(sp, 0 * kPointerSize));
+ __ mov(r2, Operand(-1));
+ __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::UInteger16());
+ __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
+ __ mov(r2, Operand(65535));
+ __ cmp(r3, r2);
+ __ b(ne, &exit);
+ __ mov(r2, Operand(65535));
+ __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::UInteger16());
+ __ cmp(r3, r2);
+ __ b(ne, &exit);
+
+ // Test 4.
+ __ mov(r0, Operand(4)); // Test number.
+ __ mov(r1, Operand(0));
+ __ str(r1, MemOperand(sp, 0 * kPointerSize));
+ __ mov(r2, Operand(-1));
+ __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::Integer16());
+ __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
+ __ mov(r2, Operand(65535));
+ __ cmp(r3, r2);
+ __ b(ne, &exit);
+ __ mov(r2, Operand(-1));
+ __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::Integer16());
+ __ cmp(r3, r2);
+ __ b(ne, &exit);
+
+ __ mov(r0, Operand(0)); // Success.
+ __ bind(&exit);
+ __ add(sp, sp, Operand(1 * kPointerSize));
+ __ bx(lr);
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ // Call the function from C++.
+
+ F0 f = FUNCTION_CAST<F0>(buffer);
+ int32_t result = Simulator::current(Isolate::Current())->Call(
+ FUNCTION_ADDR(f), 4, 0, 0, 0, 0);
+ CHECK_EQ(0, result);
+}
#undef __
--- /dev/null
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdlib.h>
+
+#include "v8.h"
+
+#include "macro-assembler.h"
+#include "factory.h"
+#include "platform.h"
+#include "serialize.h"
+#include "cctest.h"
+
+using namespace v8::internal;
+
+#if __GNUC__
+#define STDCALL __attribute__((stdcall))
+#else
+#define STDCALL __stdcall
+#endif
+
+typedef int STDCALL F0Type();
+typedef F0Type* F0;
+
+#define __ masm->
+
+
+TEST(LoadAndStoreWithRepresentation) {
+ v8::internal::V8::Initialize(NULL);
+
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
+ &actual_size,
+ true));
+ CHECK(buffer);
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope handles(isolate);
+ MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size));
+ MacroAssembler* masm = &assembler; // Create a pointer for the __ macro.
+ masm->set_allow_stub_calls(false);
+ __ push(ebx);
+ __ push(edx);
+ __ sub(esp, Immediate(1 * kPointerSize));
+ Label exit;
+
+ // Test 1.
+ __ mov(eax, Immediate(1)); // Test number.
+ __ mov(Operand(esp, 0 * kPointerSize), Immediate(0));
+ __ mov(ebx, Immediate(-1));
+ __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::UInteger8());
+ __ mov(ebx, Operand(esp, 0 * kPointerSize));
+ __ mov(edx, Immediate(255));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+ __ Load(ebx, Operand(esp, 0 * kPointerSize), Representation::UInteger8());
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+
+
+ // Test 2.
+ __ mov(eax, Immediate(2)); // Test number.
+ __ mov(Operand(esp, 0 * kPointerSize), Immediate(0));
+ __ mov(ebx, Immediate(-1));
+ __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::Integer8());
+ __ mov(ebx, Operand(esp, 0 * kPointerSize));
+ __ mov(edx, Immediate(255));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+ __ Load(ebx, Operand(esp, 0 * kPointerSize), Representation::Integer8());
+ __ mov(edx, Immediate(-1));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+
+ // Test 3.
+ __ mov(eax, Immediate(3)); // Test number.
+ __ mov(Operand(esp, 0 * kPointerSize), Immediate(0));
+ __ mov(ebx, Immediate(-1));
+ __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::Integer16());
+ __ mov(ebx, Operand(esp, 0 * kPointerSize));
+ __ mov(edx, Immediate(65535));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+ __ Load(edx, Operand(esp, 0 * kPointerSize), Representation::Integer16());
+ __ mov(ebx, Immediate(-1));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+
+ // Test 4.
+ __ mov(eax, Immediate(4)); // Test number.
+ __ mov(Operand(esp, 0 * kPointerSize), Immediate(0));
+ __ mov(ebx, Immediate(-1));
+ __ Store(ebx, Operand(esp, 0 * kPointerSize), Representation::UInteger16());
+ __ mov(ebx, Operand(esp, 0 * kPointerSize));
+ __ mov(edx, Immediate(65535));
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+ __ Load(edx, Operand(esp, 0 * kPointerSize), Representation::UInteger16());
+ __ cmp(ebx, edx);
+ __ j(not_equal, &exit);
+
+ __ xor_(eax, eax); // Success.
+ __ bind(&exit);
+ __ add(esp, Immediate(1 * kPointerSize));
+ __ pop(edx);
+ __ pop(ebx);
+ __ ret(0);
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ // Call the function from C++.
+ int result = FUNCTION_CAST<F0>(buffer)();
+ CHECK_EQ(0, result);
+}
+
+#undef __
__ movq(rax, Immediate(1)); // Test number.
__ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
__ movq(rcx, Immediate(-1));
- __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Byte());
+ __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::UInteger8());
__ movq(rcx, Operand(rsp, 0 * kPointerSize));
__ movl(rdx, Immediate(255));
__ cmpq(rcx, rdx);
__ j(not_equal, &exit);
- __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Byte());
+ __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::UInteger8());
__ cmpq(rcx, rdx);
__ j(not_equal, &exit);
__ cmpq(rcx, rdx);
__ j(not_equal, &exit);
+ // Test 7.
+ __ movq(rax, Immediate(7)); // Test number.
+ __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
+ __ movq(rcx, Immediate(-1));
+ __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Integer8());
+ __ movq(rcx, Operand(rsp, 0 * kPointerSize));
+ __ movl(rdx, Immediate(255));
+ __ cmpq(rcx, rdx);
+ __ j(not_equal, &exit);
+ __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Integer8());
+ __ movq(rcx, Immediate(-1));
+ __ cmpq(rcx, rdx);
+ __ j(not_equal, &exit);
+
+ // Test 8.
+ __ movq(rax, Immediate(8)); // Test number.
+ __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
+ __ movq(rcx, Immediate(-1));
+ __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::Integer16());
+ __ movq(rcx, Operand(rsp, 0 * kPointerSize));
+ __ movl(rdx, Immediate(65535));
+ __ cmpq(rcx, rdx);
+ __ j(not_equal, &exit);
+ __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::Integer16());
+ __ movq(rcx, Immediate(-1));
+ __ cmpq(rcx, rdx);
+ __ j(not_equal, &exit);
+
+ // Test 9.
+ __ movq(rax, Immediate(9)); // Test number.
+ __ movq(Operand(rsp, 0 * kPointerSize), Immediate(0));
+ __ movq(rcx, Immediate(-1));
+ __ Store(Operand(rsp, 0 * kPointerSize), rcx, Representation::UInteger16());
+ __ movq(rcx, Operand(rsp, 0 * kPointerSize));
+ __ movl(rdx, Immediate(65535));
+ __ cmpq(rcx, rdx);
+ __ j(not_equal, &exit);
+ __ Load(rdx, Operand(rsp, 0 * kPointerSize), Representation::UInteger16());
+ __ cmpq(rcx, rdx);
+ __ j(not_equal, &exit);
+
__ xor_(rax, rax); // Success.
__ bind(&exit);
__ addq(rsp, Immediate(1 * kPointerSize));
--- /dev/null
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "cctest.h"
+#include "types.h"
+#include "property-details.h"
+
+using namespace v8::internal;
+
+
+void TestPairPositive(Representation more_general,
+ Representation less_general) {
+ CHECK(more_general.is_more_general_than(less_general));
+}
+
+
+void TestPairNegative(Representation more_general,
+ Representation less_general) {
+ CHECK(!more_general.is_more_general_than(less_general));
+}
+
+
+TEST(RepresentationMoreGeneralThan) {
+ TestPairNegative(Representation::None(), Representation::None());
+ TestPairPositive(Representation::Integer8(), Representation::None());
+ TestPairPositive(Representation::UInteger8(), Representation::None());
+ TestPairPositive(Representation::Integer16(), Representation::None());
+ TestPairPositive(Representation::UInteger16(), Representation::None());
+ TestPairPositive(Representation::Smi(), Representation::None());
+ TestPairPositive(Representation::Integer32(), Representation::None());
+ TestPairPositive(Representation::HeapObject(), Representation::None());
+ TestPairPositive(Representation::Double(), Representation::None());
+ TestPairPositive(Representation::Tagged(), Representation::None());
+
+ TestPairNegative(Representation::None(), Representation::Integer8());
+ TestPairNegative(Representation::Integer8(), Representation::Integer8());
+ TestPairNegative(Representation::UInteger8(), Representation::Integer8());
+ TestPairPositive(Representation::Integer16(), Representation::Integer8());
+ TestPairPositive(Representation::UInteger16(), Representation::Integer8());
+ TestPairPositive(Representation::Smi(), Representation::Integer8());
+ TestPairPositive(Representation::Integer32(), Representation::Integer8());
+ TestPairNegative(Representation::HeapObject(), Representation::Integer8());
+ TestPairPositive(Representation::Double(), Representation::Integer8());
+ TestPairPositive(Representation::Tagged(), Representation::Integer8());
+
+ TestPairNegative(Representation::None(), Representation::UInteger8());
+ TestPairNegative(Representation::Integer8(), Representation::UInteger8());
+ TestPairNegative(Representation::UInteger8(), Representation::UInteger8());
+ TestPairPositive(Representation::Integer16(), Representation::UInteger8());
+ TestPairPositive(Representation::UInteger16(), Representation::UInteger8());
+ TestPairPositive(Representation::Smi(), Representation::UInteger8());
+ TestPairPositive(Representation::Integer32(), Representation::UInteger8());
+ TestPairNegative(Representation::HeapObject(), Representation::UInteger8());
+ TestPairPositive(Representation::Double(), Representation::UInteger8());
+ TestPairPositive(Representation::Tagged(), Representation::UInteger8());
+
+ TestPairNegative(Representation::None(), Representation::Integer16());
+ TestPairNegative(Representation::Integer8(), Representation::Integer16());
+ TestPairNegative(Representation::UInteger8(), Representation::Integer16());
+ TestPairNegative(Representation::Integer16(), Representation::Integer16());
+ TestPairNegative(Representation::UInteger16(), Representation::Integer16());
+ TestPairPositive(Representation::Smi(), Representation::Integer16());
+ TestPairPositive(Representation::Integer32(), Representation::Integer16());
+ TestPairNegative(Representation::HeapObject(), Representation::Integer16());
+ TestPairPositive(Representation::Double(), Representation::Integer16());
+ TestPairPositive(Representation::Tagged(), Representation::Integer16());
+
+ TestPairNegative(Representation::None(), Representation::UInteger16());
+ TestPairNegative(Representation::Integer8(), Representation::UInteger16());
+ TestPairNegative(Representation::UInteger8(), Representation::UInteger16());
+ TestPairNegative(Representation::Integer16(), Representation::UInteger16());
+ TestPairNegative(Representation::UInteger16(), Representation::UInteger16());
+ TestPairPositive(Representation::Smi(), Representation::UInteger16());
+ TestPairPositive(Representation::Integer32(), Representation::UInteger16());
+ TestPairNegative(Representation::HeapObject(), Representation::UInteger16());
+ TestPairPositive(Representation::Double(), Representation::UInteger16());
+ TestPairPositive(Representation::Tagged(), Representation::UInteger16());
+
+ TestPairNegative(Representation::None(), Representation::Smi());
+ TestPairNegative(Representation::Integer8(), Representation::Smi());
+ TestPairNegative(Representation::UInteger8(), Representation::Smi());
+ TestPairNegative(Representation::Integer16(), Representation::Smi());
+ TestPairNegative(Representation::UInteger16(), Representation::Smi());
+ TestPairNegative(Representation::Smi(), Representation::Smi());
+ TestPairPositive(Representation::Integer32(), Representation::Smi());
+ TestPairNegative(Representation::HeapObject(), Representation::Smi());
+ TestPairPositive(Representation::Double(), Representation::Smi());
+ TestPairPositive(Representation::Tagged(), Representation::Smi());
+
+ TestPairNegative(Representation::None(), Representation::Integer32());
+ TestPairNegative(Representation::Integer8(), Representation::Integer32());
+ TestPairNegative(Representation::UInteger8(), Representation::Integer32());
+ TestPairNegative(Representation::Integer16(), Representation::Integer32());
+ TestPairNegative(Representation::UInteger16(), Representation::Integer32());
+ TestPairNegative(Representation::Smi(), Representation::Integer32());
+ TestPairNegative(Representation::Integer32(), Representation::Integer32());
+ TestPairNegative(Representation::HeapObject(), Representation::Integer32());
+ TestPairPositive(Representation::Double(), Representation::Integer32());
+ TestPairPositive(Representation::Tagged(), Representation::Integer32());
+}