Bug 899139 - Part 1: Refactor value-to-int logic into IonMacroAssembler. (r=jandem)

This commit is contained in:
Shu-yu Guo 2013-09-09 18:55:52 -07:00
Родитель f39b202b1a
Коммит 27393bfaa7
10 изменённых файлов: 493 добавлений и 139 удалений

Просмотреть файл

@ -5981,7 +5981,8 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
case RetType::Void:
break;
case RetType::Signed:
masm.convertValueToInt32(JSReturnOperand, ReturnFloatReg, ReturnReg, &oolConvert);
masm.convertValueToInt32(JSReturnOperand, ReturnFloatReg, ReturnReg, &oolConvert,
/* -0 check */ false);
break;
case RetType::Double:
masm.convertValueToDouble(JSReturnOperand, ReturnFloatReg, &oolConvert);

Просмотреть файл

@ -157,89 +157,36 @@ CodeGenerator::visitValueToInt32(LValueToInt32 *lir)
{
ValueOperand operand = ToValue(lir, LValueToInt32::Input);
Register output = ToRegister(lir->output());
FloatRegister temp = ToFloatRegister(lir->tempFloat());
Register tag = masm.splitTagForTest(operand);
Label done, simple, isInt32, isBool, isString, notDouble;
// Type-check switch.
MDefinition *input;
if (lir->mode() == LValueToInt32::NORMAL)
input = lir->mirNormal()->input();
else
input = lir->mirTruncate()->input();
masm.branchEqualTypeIfNeeded(MIRType_Int32, input, tag, &isInt32);
masm.branchEqualTypeIfNeeded(MIRType_Boolean, input, tag, &isBool);
// Only convert strings to int if we are in a truncation context, like
// bitwise operations.
if (lir->mode() == LValueToInt32::TRUNCATE)
masm.branchEqualTypeIfNeeded(MIRType_String, input, tag, &isString);
masm.branchTestDouble(Assembler::NotEqual, tag, &notDouble);
// If the value is a double, see if it fits in a 32-bit int. We need to ask
// the platform-specific codegenerator to do this.
FloatRegister temp = ToFloatRegister(lir->tempFloat());
masm.unboxDouble(operand, temp);
Label fails, isDouble;
masm.bind(&isDouble);
Label fails;
if (lir->mode() == LValueToInt32::TRUNCATE) {
if (!emitTruncateDouble(temp, output))
return false;
// We can only handle strings in truncation contexts, like bitwise
// operations.
if (input->mightBeType(MIRType_String)) {
Register stringReg = ToRegister(lir->temp());
OutOfLineCode *ool = oolCallVM(StringToNumberInfo, lir, (ArgList(), stringReg),
StoreFloatRegisterTo(temp));
if (!ool)
return false;
masm.truncateValueToInt32(operand, input, ool->entry(), ool->rejoin(), stringReg,
temp, output, &fails);
} else {
masm.truncateValueToInt32(operand, input, temp, output, &fails);
}
} else {
masm.convertDoubleToInt32(temp, output, &fails, lir->mirNormal()->canBeNegativeZero());
}
masm.jump(&done);
masm.bind(&notDouble);
if (lir->mode() == LValueToInt32::NORMAL) {
// If the value is not null, it's a string, object, or undefined,
// which we can't handle here.
masm.branchTestNull(Assembler::NotEqual, tag, &fails);
} else {
// Test for object - then fallthrough to null, which will also handle
// undefined.
masm.branchEqualTypeIfNeeded(MIRType_Object, input, tag, &fails);
masm.convertValueToInt32(operand, input, temp, output, &fails,
lir->mirNormal()->canBeNegativeZero());
}
if (fails.used() && !bailoutFrom(&fails, lir->snapshot()))
return false;
// The value is null - just emit 0.
masm.mov(Imm32(0), output);
masm.jump(&done);
// Unbox a string, call StringToNumber to get a double back, and jump back
// to the snippet generated above about dealing with doubles.
if (isString.used()) {
masm.bind(&isString);
Register str = masm.extractString(operand, ToRegister(lir->temp()));
OutOfLineCode *ool = oolCallVM(StringToNumberInfo, lir, (ArgList(), str),
StoreFloatRegisterTo(temp));
if (!ool)
return false;
masm.jump(ool->entry());
masm.bind(ool->rejoin());
masm.jump(&isDouble);
}
// Just unbox a bool, the result is 0 or 1.
if (isBool.used()) {
masm.bind(&isBool);
masm.unboxBoolean(operand, output);
masm.jump(&done);
}
// Integers can be unboxed.
if (isInt32.used()) {
masm.bind(&isInt32);
masm.unboxInt32(operand, output);
}
masm.bind(&done);
return true;
return bailoutFrom(&fails, lir->snapshot());
}
static const double DoubleZero = 0.0;
@ -6790,46 +6737,24 @@ CodeGenerator::visitClampDToUint8(LClampDToUint8 *lir)
bool
CodeGenerator::visitClampVToUint8(LClampVToUint8 *lir)
{
ValueOperand input = ToValue(lir, LClampVToUint8::Input);
ValueOperand operand = ToValue(lir, LClampVToUint8::Input);
FloatRegister tempFloat = ToFloatRegister(lir->tempFloat());
Register output = ToRegister(lir->output());
MDefinition *input = lir->mir()->input();
Register tag = masm.splitTagForTest(input);
Label fails;
if (input->mightBeType(MIRType_String)) {
OutOfLineCode *ool = oolCallVM(StringToNumberInfo, lir, (ArgList(), output),
StoreFloatRegisterTo(tempFloat));
masm.clampValueToUint8(operand, input, ool->entry(), ool->rejoin(), output,
tempFloat, output, &fails);
Label done;
Label isInt32, isDouble, isBoolean;
masm.branchTestInt32(Assembler::Equal, tag, &isInt32);
masm.branchTestDouble(Assembler::Equal, tag, &isDouble);
masm.branchTestBoolean(Assembler::Equal, tag, &isBoolean);
// Undefined, null and objects are always 0.
Label isZero;
masm.branchTestUndefined(Assembler::Equal, tag, &isZero);
masm.branchTestNull(Assembler::Equal, tag, &isZero);
masm.branchTestObject(Assembler::Equal, tag, &isZero);
// Bailout for everything else (strings).
if (!bailout(lir->snapshot()))
} else {
masm.clampValueToUint8(operand, input, tempFloat, output, &fails);
}
if (!bailoutFrom(&fails, lir->snapshot()))
return false;
masm.bind(&isInt32);
masm.unboxInt32(input, output);
masm.clampIntToUint8(output, output);
masm.jump(&done);
masm.bind(&isDouble);
masm.unboxDouble(input, tempFloat);
masm.clampDoubleToUint8(tempFloat, output);
masm.jump(&done);
masm.bind(&isBoolean);
masm.unboxBoolean(input, output);
masm.jump(&done);
masm.bind(&isZero);
masm.move32(Imm32(0), output);
masm.bind(&done);
return true;
}

Просмотреть файл

@ -1376,6 +1376,7 @@ MacroAssembler::convertInt32ValueToDouble(const Address &address, Register scrat
}
static const double DoubleZero = 0.0;
static const double DoubleOne = 1.0;
void
MacroAssembler::convertValueToDouble(ValueOperand value, FloatRegister output, Label *fail)
@ -1411,39 +1412,45 @@ MacroAssembler::convertValueToDouble(ValueOperand value, FloatRegister output, L
bind(&done);
}
void
MacroAssembler::convertValueToInt32(ValueOperand value, FloatRegister temp,
Register output, Label *fail)
bool
MacroAssembler::convertValueToDouble(JSContext *cx, const Value &v, FloatRegister output, Label *fail)
{
Register tag = splitTagForTest(value);
if (v.isNumber() || v.isString()) {
double d;
if (v.isNumber())
d = v.toNumber();
else if (!StringToNumber(cx, v.toString(), &d))
return false;
Label done, simple, isInt32, isBool, isDouble;
if (d == js_NaN)
loadStaticDouble(&js_NaN, output);
else
loadConstantDouble(d, output);
branchTestInt32(Assembler::Equal, tag, &isInt32);
branchTestBoolean(Assembler::Equal, tag, &isBool);
branchTestDouble(Assembler::Equal, tag, &isDouble);
branchTestNull(Assembler::NotEqual, tag, fail);
return true;
}
// The value is null - just emit 0.
mov(Imm32(0), output);
jump(&done);
if (v.isBoolean()) {
if (v.toBoolean())
loadStaticDouble(&DoubleOne, output);
else
loadStaticDouble(&DoubleZero, output);
return true;
}
// Try converting double into integer
bind(&isDouble);
unboxDouble(value, temp);
convertDoubleToInt32(temp, output, fail, /* -0 check */ false);
jump(&done);
if (v.isNull()) {
loadStaticDouble(&DoubleZero, output);
return true;
}
// Just unbox a bool, the result is 0 or 1.
bind(&isBool);
unboxBoolean(value, output);
jump(&done);
if (v.isUndefined()) {
loadStaticDouble(&js_NaN, output);
return true;
}
// Integers can be unboxed.
bind(&isInt32);
unboxInt32(value, output);
bind(&done);
JS_ASSERT(v.isObject());
jump(fail);
return true;
}
void
@ -1485,6 +1492,251 @@ MacroAssembler::popRooted(VMFunction::RootType rootType, Register cellReg,
}
}
bool
MacroAssembler::convertConstantOrRegisterToDouble(JSContext *cx, ConstantOrRegister src,
FloatRegister output, Label *fail)
{
if (src.constant())
return convertValueToDouble(cx, src.value(), output, fail);
convertTypedOrValueToDouble(src.reg(), output, fail);
return true;
}
void
MacroAssembler::convertTypedOrValueToDouble(TypedOrValueRegister src, FloatRegister output,
Label *fail)
{
if (src.hasValue()) {
convertValueToDouble(src.valueReg(), output, fail);
return;
}
switch (src.type()) {
case MIRType_Null:
loadStaticDouble(&DoubleZero, output);
break;
case MIRType_Boolean:
case MIRType_Int32:
convertInt32ToDouble(src.typedReg().gpr(), output);
break;
case MIRType_Double:
if (src.typedReg().fpu() != output)
moveDouble(src.typedReg().fpu(), output);
break;
case MIRType_Object:
case MIRType_String:
jump(fail);
break;
case MIRType_Undefined:
loadStaticDouble(&js_NaN, output);
break;
default:
MOZ_ASSUME_UNREACHABLE("Bad MIRType");
}
}
void
MacroAssembler::convertDoubleToInt(FloatRegister src, Register output, Label *fail,
IntConversionBehavior behavior)
{
switch (behavior) {
case IntConversion_Normal:
case IntConversion_NegativeZeroCheck:
convertDoubleToInt32(src, output, fail, behavior == IntConversion_NegativeZeroCheck);
break;
case IntConversion_Truncate:
branchTruncateDouble(src, output, fail);
break;
case IntConversion_ClampToUint8:
clampDoubleToUint8(src, output);
break;
}
}
void
MacroAssembler::convertValueToInt(ValueOperand value, MDefinition *maybeInput,
Label *handleStringEntry, Label *handleStringRejoin,
Register stringReg, FloatRegister temp, Register output,
Label *fail, IntConversionBehavior behavior)
{
Register tag = splitTagForTest(value);
bool handleStrings = (behavior == IntConversion_Truncate ||
behavior == IntConversion_ClampToUint8) &&
handleStringEntry &&
handleStringRejoin;
bool zeroObjects = behavior == IntConversion_ClampToUint8;
Label done, isInt32, isBool, isDouble, isNull, isString;
branchEqualTypeIfNeeded(MIRType_Int32, maybeInput, tag, &isInt32);
branchEqualTypeIfNeeded(MIRType_Boolean, maybeInput, tag, &isBool);
branchEqualTypeIfNeeded(MIRType_Double, maybeInput, tag, &isDouble);
// If we are not truncating, we fail for anything that's not
// null. Otherwise we might be able to handle strings and objects.
switch (behavior) {
case IntConversion_Normal:
case IntConversion_NegativeZeroCheck:
branchTestNull(Assembler::NotEqual, tag, fail);
break;
case IntConversion_Truncate:
case IntConversion_ClampToUint8:
branchEqualTypeIfNeeded(MIRType_Null, maybeInput, tag, &isNull);
if (handleStrings)
branchEqualTypeIfNeeded(MIRType_String, maybeInput, tag, &isString);
if (zeroObjects)
branchEqualTypeIfNeeded(MIRType_Object, maybeInput, tag, &isNull);
branchTestUndefined(Assembler::NotEqual, tag, fail);
break;
}
// The value is null or undefined in truncation contexts - just emit 0.
if (isNull.used())
bind(&isNull);
mov(Imm32(0), output);
jump(&done);
// Try converting a string into a double, then jump to the double case.
if (handleStrings) {
bind(&isString);
unboxString(value, stringReg);
jump(handleStringEntry);
}
// Try converting double into integer.
if (isDouble.used() || handleStrings) {
if (isDouble.used()) {
bind(&isDouble);
unboxDouble(value, temp);
}
if (handleStrings)
bind(handleStringRejoin);
convertDoubleToInt(temp, output, fail, behavior);
jump(&done);
}
// Just unbox a bool, the result is 0 or 1.
if (isBool.used()) {
bind(&isBool);
unboxBoolean(value, output);
jump(&done);
}
// Integers can be unboxed.
if (isInt32.used()) {
bind(&isInt32);
unboxInt32(value, output);
if (behavior == IntConversion_ClampToUint8)
clampIntToUint8(output, output);
}
bind(&done);
}
bool
MacroAssembler::convertValueToInt(JSContext *cx, const Value &v, Register output, Label *fail,
IntConversionBehavior behavior)
{
bool handleStrings = (behavior == IntConversion_Truncate ||
behavior == IntConversion_ClampToUint8);
bool zeroObjects = behavior == IntConversion_ClampToUint8;
if (v.isNumber() || (handleStrings && v.isString())) {
double d;
if (v.isNumber())
d = v.toNumber();
else if (!StringToNumber(cx, v.toString(), &d))
return false;
switch (behavior) {
case IntConversion_Normal:
case IntConversion_NegativeZeroCheck: {
// -0 is checked anyways if we have a constant value.
int i;
if (mozilla::DoubleIsInt32(d, &i))
move32(Imm32(i), output);
else
jump(fail);
break;
}
case IntConversion_Truncate:
move32(Imm32(ToInt32(d)), output);
break;
case IntConversion_ClampToUint8:
move32(Imm32(ClampDoubleToUint8(d)), output);
break;
}
return true;
}
if (v.isBoolean()) {
move32(Imm32(v.toBoolean() ? 1 : 0), output);
return true;
}
if (v.isNull() || v.isUndefined()) {
move32(Imm32(0), output);
return true;
}
JS_ASSERT(v.isObject());
if (zeroObjects)
move32(Imm32(0), output);
else
jump(fail);
return true;
}
bool
MacroAssembler::convertConstantOrRegisterToInt(JSContext *cx, ConstantOrRegister src,
FloatRegister temp, Register output,
Label *fail, IntConversionBehavior behavior)
{
if (src.constant())
return convertValueToInt(cx, src.value(), output, fail, behavior);
convertTypedOrValueToInt(src.reg(), temp, output, fail, behavior);
return true;
}
void
MacroAssembler::convertTypedOrValueToInt(TypedOrValueRegister src, FloatRegister temp,
Register output, Label *fail,
IntConversionBehavior behavior)
{
if (src.hasValue()) {
convertValueToInt(src.valueReg(), temp, output, fail, behavior);
return;
}
switch (src.type()) {
case MIRType_Undefined:
case MIRType_Null:
move32(Imm32(0), output);
break;
case MIRType_Boolean:
case MIRType_Int32:
if (src.typedReg().gpr() != output)
move32(src.typedReg().gpr(), output);
break;
case MIRType_Double:
convertDoubleToInt(src.typedReg().fpu(), output, fail, behavior);
break;
case MIRType_String:
case MIRType_Object:
jump(fail);
break;
default:
MOZ_ASSUME_UNREACHABLE("Bad MIRType");
}
}
void
MacroAssembler::finish()
{
@ -1542,10 +1794,10 @@ MacroAssembler::branchIfNotInterpretedConstructor(Register fun, Register scratch
}
void
MacroAssembler::branchEqualTypeIfNeeded(MIRType type, MDefinition *def, const Register &tag,
MacroAssembler::branchEqualTypeIfNeeded(MIRType type, MDefinition *maybeDef, const Register &tag,
Label *label)
{
if (def->mightBeType(type)) {
if (!maybeDef || maybeDef->mightBeType(type)) {
switch (type) {
case MIRType_Null:
branchTestNull(Equal, tag, label);

Просмотреть файл

@ -630,7 +630,8 @@ class MacroAssembler : public MacroAssemblerSpecific
using MacroAssemblerSpecific::ensureDouble;
void ensureDouble(const Address &source, FloatRegister dest, Label *failure) {
template <typename S>
void ensureDouble(const S &source, FloatRegister dest, Label *failure) {
Label isDouble, done;
branchTestDouble(Assembler::Equal, source, &isDouble);
branchTestInt32(Assembler::NotEqual, source, failure);
@ -646,7 +647,7 @@ class MacroAssembler : public MacroAssemblerSpecific
// Emit type case branch on tag matching if the type tag in the definition
// might actually be that type.
void branchEqualTypeIfNeeded(MIRType type, MDefinition *def, const Register &tag,
void branchEqualTypeIfNeeded(MIRType type, MDefinition *maybeDef, const Register &tag,
Label *label);
// Inline allocation.
@ -997,7 +998,151 @@ class MacroAssembler : public MacroAssemblerSpecific
void convertInt32ValueToDouble(const Address &address, Register scratch, Label *done);
void convertValueToDouble(ValueOperand value, FloatRegister output, Label *fail);
void convertValueToInt32(ValueOperand value, FloatRegister temp, Register output, Label *fail);
bool convertValueToDouble(JSContext *cx, const Value &v, FloatRegister output, Label *fail);
bool convertConstantOrRegisterToDouble(JSContext *cx, ConstantOrRegister src,
FloatRegister output, Label *fail);
void convertTypedOrValueToDouble(TypedOrValueRegister src, FloatRegister output, Label *fail);
enum IntConversionBehavior {
IntConversion_Normal,
IntConversion_NegativeZeroCheck,
IntConversion_Truncate,
IntConversion_ClampToUint8,
};
//
// Functions for converting values to int.
//
void convertDoubleToInt(FloatRegister src, Register output, Label *fail,
IntConversionBehavior behavior);
// Strings may be handled by providing labels to jump to when the behavior
// is truncation or clamping. The subroutine, usually an OOL call, is
// passed the unboxed string in |stringReg| and should convert it to a
// double store into |temp|.
void convertValueToInt(ValueOperand value, MDefinition *input,
Label *handleStringEntry, Label *handleStringRejoin,
Register stringReg, FloatRegister temp, Register output,
Label *fail, IntConversionBehavior behavior);
void convertValueToInt(ValueOperand value, FloatRegister temp, Register output, Label *fail,
IntConversionBehavior behavior)
{
convertValueToInt(value, NULL, NULL, NULL, InvalidReg, temp, output, fail, behavior);
}
bool convertValueToInt(JSContext *cx, const Value &v, Register output, Label *fail,
IntConversionBehavior behavior);
bool convertConstantOrRegisterToInt(JSContext *cx, ConstantOrRegister src, FloatRegister temp,
Register output, Label *fail, IntConversionBehavior behavior);
void convertTypedOrValueToInt(TypedOrValueRegister src, FloatRegister temp, Register output,
Label *fail, IntConversionBehavior behavior);
//
// Convenience functions for converting values to int32.
//
void convertValueToInt32(ValueOperand value, FloatRegister temp, Register output, Label *fail,
bool negativeZeroCheck)
{
convertValueToInt(value, temp, output, fail, negativeZeroCheck
? IntConversion_NegativeZeroCheck
: IntConversion_Normal);
}
void convertValueToInt32(ValueOperand value, MDefinition *input,
FloatRegister temp, Register output, Label *fail,
bool negativeZeroCheck)
{
convertValueToInt(value, input, NULL, NULL, InvalidReg, temp, output, fail,
negativeZeroCheck
? IntConversion_NegativeZeroCheck
: IntConversion_Normal);
}
bool convertValueToInt32(JSContext *cx, const Value &v, Register output, Label *fail,
bool negativeZeroCheck)
{
return convertValueToInt(cx, v, output, fail, negativeZeroCheck
? IntConversion_NegativeZeroCheck
: IntConversion_Normal);
}
bool convertConstantOrRegisterToInt32(JSContext *cx, ConstantOrRegister src, FloatRegister temp,
Register output, Label *fail, bool negativeZeroCheck)
{
return convertConstantOrRegisterToInt(cx, src, temp, output, fail, negativeZeroCheck
? IntConversion_NegativeZeroCheck
: IntConversion_Normal);
}
void convertTypedOrValueToInt32(TypedOrValueRegister src, FloatRegister temp, Register output,
Label *fail, bool negativeZeroCheck)
{
convertTypedOrValueToInt(src, temp, output, fail, negativeZeroCheck
? IntConversion_NegativeZeroCheck
: IntConversion_Normal);
}
//
// Convenience functions for truncating values to int32.
//
void truncateValueToInt32(ValueOperand value, FloatRegister temp, Register output, Label *fail) {
convertValueToInt(value, temp, output, fail, IntConversion_Truncate);
}
void truncateValueToInt32(ValueOperand value, MDefinition *input,
Label *handleStringEntry, Label *handleStringRejoin,
Register stringReg, FloatRegister temp, Register output,
Label *fail)
{
convertValueToInt(value, input, handleStringEntry, handleStringRejoin,
stringReg, temp, output, fail, IntConversion_Truncate);
}
void truncateValueToInt32(ValueOperand value, MDefinition *input,
FloatRegister temp, Register output, Label *fail)
{
convertValueToInt(value, input, NULL, NULL, InvalidReg, temp, output, fail,
IntConversion_Truncate);
}
bool truncateValueToInt32(JSContext *cx, const Value &v, Register output, Label *fail) {
return convertValueToInt(cx, v, output, fail, IntConversion_Truncate);
}
bool truncateConstantOrRegisterToInt32(JSContext *cx, ConstantOrRegister src, FloatRegister temp,
Register output, Label *fail)
{
return convertConstantOrRegisterToInt(cx, src, temp, output, fail, IntConversion_Truncate);
}
void truncateTypedOrValueToInt32(TypedOrValueRegister src, FloatRegister temp, Register output,
Label *fail)
{
convertTypedOrValueToInt(src, temp, output, fail, IntConversion_Truncate);
}
// Convenience functions for clamping values to uint8.
void clampValueToUint8(ValueOperand value, FloatRegister temp, Register output, Label *fail) {
convertValueToInt(value, temp, output, fail, IntConversion_ClampToUint8);
}
void clampValueToUint8(ValueOperand value, MDefinition *input,
Label *handleStringEntry, Label *handleStringRejoin,
Register stringReg, FloatRegister temp, Register output,
Label *fail)
{
convertValueToInt(value, input, handleStringEntry, handleStringRejoin,
stringReg, temp, output, fail, IntConversion_ClampToUint8);
}
void clampValueToUint8(ValueOperand value, MDefinition *input,
FloatRegister temp, Register output, Label *fail)
{
convertValueToInt(value, input, NULL, NULL, InvalidReg, temp, output, fail,
IntConversion_ClampToUint8);
}
bool clampValueToUint8(JSContext *cx, const Value &v, Register output, Label *fail) {
return convertValueToInt(cx, v, output, fail, IntConversion_ClampToUint8);
}
bool clampConstantOrRegisterToUint8(JSContext *cx, ConstantOrRegister src, FloatRegister temp,
Register output, Label *fail)
{
return convertConstantOrRegisterToInt(cx, src, temp, output, fail,
IntConversion_ClampToUint8);
}
void clampTypedOrValueToUint8(TypedOrValueRegister src, FloatRegister temp, Register output,
Label *fail)
{
convertTypedOrValueToInt(src, temp, output, fail, IntConversion_ClampToUint8);
}
};
static inline Assembler::DoubleCondition

Просмотреть файл

@ -3647,6 +3647,9 @@ class LClampVToUint8 : public LInstructionHelper<1, BOX_PIECES, 1>
const LDefinition *tempFloat() {
return getTemp(0);
}
const MClampToUint8 *mir() const {
return mir_->toClampToUint8();
}
};
// Load a boxed value from an object's fixed slot.

Просмотреть файл

@ -2366,7 +2366,7 @@ LIRGenerator::visitClampToUint8(MClampToUint8 *ins)
LClampVToUint8 *lir = new LClampVToUint8(tempFloat());
if (!useBox(lir, LClampVToUint8::Input, in))
return false;
return assignSnapshot(lir) && define(lir, ins);
return assignSnapshot(lir) && define(lir, ins) && assignSafepoint(lir, ins);
}
default:

Просмотреть файл

@ -1734,6 +1734,12 @@ MacroAssemblerARMCompat::move32(const Imm32 &imm, const Register &dest)
{
ma_mov(imm, dest);
}
void
MacroAssemblerARMCompat::move32(const Register &src, const Register &dest) {
ma_mov(src, dest);
}
void
MacroAssemblerARMCompat::movePtr(const Register &src, const Register &dest)
{
@ -2582,6 +2588,16 @@ MacroAssemblerARMCompat::unboxDouble(const Address &src, const FloatRegister &de
ma_vldr(Operand(src), dest);
}
void
MacroAssemblerARMCompat::unboxString(const ValueOperand &operand, const Register &dest) {
ma_mov(operand.payloadReg(), dest);
}
void
MacroAssemblerARMCompat::unboxString(const Address &src, const Register &dest) {
ma_ldr(payloadOf(src), dest);
}
void
MacroAssemblerARMCompat::unboxValue(const ValueOperand &src, AnyRegister dest)
{

Просмотреть файл

@ -718,6 +718,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
void unboxBoolean(const Address &src, const Register &dest);
void unboxDouble(const ValueOperand &operand, const FloatRegister &dest);
void unboxDouble(const Address &src, const FloatRegister &dest);
void unboxString(const ValueOperand &operand, const Register &dest);
void unboxString(const Address &src, const Register &dest);
void unboxValue(const ValueOperand &src, AnyRegister dest);
void unboxPrivate(const ValueOperand &src, Register dest);
@ -1176,6 +1178,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
void addPtr(const Address &src, Register dest);
void move32(const Imm32 &imm, const Register &dest);
void move32(const Register &src, const Register &dest);
void movePtr(const Register &src, const Register &dest);
void movePtr(const ImmWord &imm, const Register &dest);

Просмотреть файл

@ -99,6 +99,9 @@ class MacroAssemblerX86Shared : public Assembler
void move32(const Imm32 &imm, const Operand &dest) {
movl(imm, dest);
}
void move32(const Register &src, const Register &dest) {
movl(src, dest);
}
void and32(const Imm32 &imm, const Register &dest) {
andl(imm, dest);
}

Просмотреть файл

@ -774,6 +774,12 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
unpcklps(ScratchFloatReg, dest);
}
}
void unboxString(const ValueOperand &src, const Register &dest) {
movl(src.payloadReg(), dest);
}
void unboxString(const Address &src, const Register &dest) {
movl(payloadOf(src), dest);
}
void unboxValue(const ValueOperand &src, AnyRegister dest) {
if (dest.isFloat()) {
Label notInt32, end;