| Index: src/mips/macro-assembler-mips.cc
|
| diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
|
| index 77d03b5554909215a4ce23324276c19efb2b3175..2072b39e7a6d7240b2236f148f34724a6a2d2926 100644
|
| --- a/src/mips/macro-assembler-mips.cc
|
| +++ b/src/mips/macro-assembler-mips.cc
|
| @@ -574,12 +574,22 @@ void MacroAssembler::Subu(Register rd, Register rs, const Operand& rt) {
|
|
|
| void MacroAssembler::Mul(Register rd, Register rs, const Operand& rt) {
|
| if (rt.is_reg()) {
|
| - mul(rd, rs, rt.rm());
|
| + if (kArchVariant == kLoongson) {
|
| + mult(rs, rt.rm());
|
| + mflo(rd);
|
| + } else {
|
| + mul(rd, rs, rt.rm());
|
| + }
|
| } else {
|
| // li handles the relocation.
|
| ASSERT(!rs.is(at));
|
| li(at, rt);
|
| - mul(rd, rs, at);
|
| + if (kArchVariant == kLoongson) {
|
| + mult(rs, at);
|
| + mflo(rd);
|
| + } else {
|
| + mul(rd, rs, at);
|
| + }
|
| }
|
| }
|
|
|
| @@ -734,7 +744,7 @@ void MacroAssembler::Sltu(Register rd, Register rs, const Operand& rt) {
|
|
|
|
|
| void MacroAssembler::Ror(Register rd, Register rs, const Operand& rt) {
|
| - if (mips32r2) {
|
| + if (kArchVariant == kMips32r2) {
|
| if (rt.is_reg()) {
|
| rotrv(rd, rs, rt.rm());
|
| } else {
|
| @@ -922,7 +932,7 @@ void MacroAssembler::Ext(Register rt,
|
| ASSERT(pos < 32);
|
| ASSERT(pos + size < 33);
|
|
|
| - if (mips32r2) {
|
| + if (kArchVariant == kMips32r2) {
|
| ext_(rt, rs, pos, size);
|
| } else {
|
| // Move rs to rt and shift it left then right to get the
|
| @@ -946,7 +956,7 @@ void MacroAssembler::Ins(Register rt,
|
| ASSERT(pos + size <= 32);
|
| ASSERT(size != 0);
|
|
|
| - if (mips32r2) {
|
| + if (kArchVariant == kMips32r2) {
|
| ins_(rt, rs, pos, size);
|
| } else {
|
| ASSERT(!rt.is(t8) && !rs.is(t8));
|
| @@ -1016,6 +1026,48 @@ void MacroAssembler::Trunc_uw_d(FPURegister fd,
|
| mtc1(t8, fd);
|
| }
|
|
|
| +void MacroAssembler::Trunc_w_d(FPURegister fd, FPURegister fs) {
|
| + if (kArchVariant == kLoongson && fd.is(fs)) {
|
| + mfc1(t8, FPURegister::from_code(fs.code() + 1));
|
| + trunc_w_d(fd, fs);
|
| + mtc1(t8, FPURegister::from_code(fs.code() + 1));
|
| + } else {
|
| + trunc_w_d(fd, fs);
|
| + }
|
| +}
|
| +
|
| +void MacroAssembler::Round_w_d(FPURegister fd, FPURegister fs) {
|
| + if (kArchVariant == kLoongson && fd.is(fs)) {
|
| + mfc1(t8, FPURegister::from_code(fs.code() + 1));
|
| + round_w_d(fd, fs);
|
| + mtc1(t8, FPURegister::from_code(fs.code() + 1));
|
| + } else {
|
| + round_w_d(fd, fs);
|
| + }
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::Floor_w_d(FPURegister fd, FPURegister fs) {
|
| + if (kArchVariant == kLoongson && fd.is(fs)) {
|
| + mfc1(t8, FPURegister::from_code(fs.code() + 1));
|
| + floor_w_d(fd, fs);
|
| + mtc1(t8, FPURegister::from_code(fs.code() + 1));
|
| + } else {
|
| + floor_w_d(fd, fs);
|
| + }
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::Ceil_w_d(FPURegister fd, FPURegister fs) {
|
| + if (kArchVariant == kLoongson && fd.is(fs)) {
|
| + mfc1(t8, FPURegister::from_code(fs.code() + 1));
|
| + ceil_w_d(fd, fs);
|
| + mtc1(t8, FPURegister::from_code(fs.code() + 1));
|
| + } else {
|
| + ceil_w_d(fd, fs);
|
| + }
|
| +}
|
| +
|
|
|
| void MacroAssembler::Trunc_uw_d(FPURegister fd,
|
| Register rs,
|
| @@ -1146,6 +1198,104 @@ void MacroAssembler::Move(FPURegister dst, double imm) {
|
| }
|
|
|
|
|
| +void MacroAssembler::Movz(Register rd, Register rs, Register rt) {
|
| + if (kArchVariant == kLoongson) {
|
| + Label done;
|
| + Branch(&done, ne, rt, Operand(zero_reg));
|
| + mov(rd, rs);
|
| + bind(&done);
|
| + } else {
|
| + movz(rd, rs, rt);
|
| + }
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::Movn(Register rd, Register rs, Register rt) {
|
| + if (kArchVariant == kLoongson) {
|
| + Label done;
|
| + Branch(&done, eq, rt, Operand(zero_reg));
|
| + mov(rd, rs);
|
| + bind(&done);
|
| + } else {
|
| + movn(rd, rs, rt);
|
| + }
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::Movt(Register rd, Register rs, uint16_t cc) {
|
| + if (kArchVariant == kLoongson) {
|
| + // Tests an FP condition code and then conditionally move rs to rd.
|
| + // We do not currently use any FPU cc bit other than bit 0.
|
| + ASSERT(cc == 0);
|
| + ASSERT(!(rs.is(t8) || rd.is(t8)));
|
| + Label done;
|
| + Register scratch = t8;
|
| + // For testing purposes we need to fetch content of the FCSR register and
|
| + // than test its cc (floating point condition code) bit (for cc = 0, it is
|
| + // 24. bit of the FCSR).
|
| + cfc1(scratch, FCSR);
|
| + // For the MIPS I, II and III architectures, the contents of scratch is
|
| + // UNPREDICTABLE for the instruction immediately following CFC1.
|
| + nop();
|
| + srl(scratch, scratch, 16);
|
| + andi(scratch, scratch, 0x0080);
|
| + Branch(&done, eq, scratch, Operand(zero_reg));
|
| + mov(rd, rs);
|
| + bind(&done);
|
| + } else {
|
| + movt(rd, rs, cc);
|
| + }
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::Movf(Register rd, Register rs, uint16_t cc) {
|
| + if (kArchVariant == kLoongson) {
|
| + // Tests an FP condition code and then conditionally move rs to rd.
|
| + // We do not currently use any FPU cc bit other than bit 0.
|
| + ASSERT(cc == 0);
|
| + ASSERT(!(rs.is(t8) || rd.is(t8)));
|
| + Label done;
|
| + Register scratch = t8;
|
| + // For testing purposes we need to fetch content of the FCSR register and
|
| + // than test its cc (floating point condition code) bit (for cc = 0, it is
|
| + // 24. bit of the FCSR).
|
| + cfc1(scratch, FCSR);
|
| + // For the MIPS I, II and III architectures, the contents of scratch is
|
| + // UNPREDICTABLE for the instruction immediately following CFC1.
|
| + nop();
|
| + srl(scratch, scratch, 16);
|
| + andi(scratch, scratch, 0x0080);
|
| + Branch(&done, ne, scratch, Operand(zero_reg));
|
| + mov(rd, rs);
|
| + bind(&done);
|
| + } else {
|
| + movf(rd, rs, cc);
|
| + }
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::Clz(Register rd, Register rs) {
|
| + if (kArchVariant == kLoongson) {
|
| + ASSERT(!(rd.is(t8) || rd.is(t9)) && !(rs.is(t8) || rs.is(t9)));
|
| + Register mask = t8;
|
| + Register scratch = t9;
|
| + Label loop, end;
|
| + mov(at, rs);
|
| + mov(rd, zero_reg);
|
| + lui(mask, 0x8000);
|
| + bind(&loop);
|
| + and_(scratch, at, mask);
|
| + Branch(&end, ne, scratch, Operand(zero_reg));
|
| + addiu(rd, rd, 1);
|
| + Branch(&loop, ne, mask, Operand(zero_reg), USE_DELAY_SLOT);
|
| + srl(mask, mask, 1);
|
| + bind(&end);
|
| + } else {
|
| + clz(rd, rs);
|
| + }
|
| +}
|
| +
|
| +
|
| // Tries to get a signed int32 out of a double precision floating point heap
|
| // number. Rounds towards 0. Branch to 'not_int32' if the double is out of the
|
| // 32bits signed integer range.
|
| @@ -1236,8 +1386,8 @@ void MacroAssembler::ConvertToInt32(Register source,
|
| subu(scratch2, zero_reg, scratch);
|
| // Trick to check sign bit (msb) held in dest, count leading zero.
|
| // 0 indicates negative, save negative version with conditional move.
|
| - clz(dest, dest);
|
| - movz(scratch, scratch2, dest);
|
| + Clz(dest, dest);
|
| + Movz(scratch, scratch2, dest);
|
| mov(dest, scratch);
|
| }
|
| bind(&done);
|
| @@ -1268,16 +1418,16 @@ void MacroAssembler::EmitFPUTruncate(FPURoundingMode rounding_mode,
|
| // Do operation based on rounding mode.
|
| switch (rounding_mode) {
|
| case kRoundToNearest:
|
| - round_w_d(result, double_input);
|
| + Round_w_d(result, double_input);
|
| break;
|
| case kRoundToZero:
|
| - trunc_w_d(result, double_input);
|
| + Trunc_w_d(result, double_input);
|
| break;
|
| case kRoundToPlusInf:
|
| - ceil_w_d(result, double_input);
|
| + Ceil_w_d(result, double_input);
|
| break;
|
| case kRoundToMinusInf:
|
| - floor_w_d(result, double_input);
|
| + Floor_w_d(result, double_input);
|
| break;
|
| } // End of switch-statement.
|
|
|
| @@ -1304,7 +1454,7 @@ void MacroAssembler::EmitOutOfInt32RangeTruncate(Register result,
|
|
|
| // Check for Infinity and NaNs, which should return 0.
|
| Subu(scratch, result, HeapNumber::kExponentMask);
|
| - movz(result, zero_reg, scratch);
|
| + Movz(result, zero_reg, scratch);
|
| Branch(&done, eq, scratch, Operand(zero_reg));
|
|
|
| // Express exponent as delta to (number of mantissa bits + 31).
|
| @@ -1368,7 +1518,7 @@ void MacroAssembler::EmitOutOfInt32RangeTruncate(Register result,
|
| result = sign;
|
| sign = no_reg;
|
| Subu(result, zero_reg, input_high);
|
| - movz(result, input_high, scratch);
|
| + Movz(result, input_high, scratch);
|
| bind(&done);
|
| }
|
|
|
|
|