Skip to content

Commit

Permalink
MIPS: Added support for Loongson architectures.
Browse files Browse the repository at this point in the history
BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9692048
Patch from Daniel Kalmar <kalmard@homejinni.com>.

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@11032 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
  • Loading branch information
yangguo@chromium.org committed Mar 13, 2012
1 parent a220b7c commit 6fa2e17
Show file tree
Hide file tree
Showing 16 changed files with 345 additions and 138 deletions.
20 changes: 19 additions & 1 deletion SConstruct
Expand Up @@ -185,6 +185,9 @@ LIBRARY_FLAGS = {
'mips_arch_variant:mips32r2': {
'CPPDEFINES': ['_MIPS_ARCH_MIPS32R2']
},
'mips_arch_variant:loongson': {
'CPPDEFINES': ['_MIPS_ARCH_LOONGSON']
},
'simulator:none': {
'CCFLAGS': ['-EL'],
'LINKFLAGS': ['-EL'],
Expand All @@ -194,6 +197,9 @@ LIBRARY_FLAGS = {
'mips_arch_variant:mips32r1': {
'CCFLAGS': ['-mips32', '-Wa,-mips32']
},
'mips_arch_variant:loongson': {
'CCFLAGS': ['-march=mips3', '-Wa,-march=mips3']
},
'library:static': {
'LINKFLAGS': ['-static', '-static-libgcc']
},
Expand Down Expand Up @@ -545,6 +551,9 @@ SAMPLE_FLAGS = {
'mips_arch_variant:mips32r2': {
'CPPDEFINES': ['_MIPS_ARCH_MIPS32R2']
},
'mips_arch_variant:loongson': {
'CPPDEFINES': ['_MIPS_ARCH_LOONGSON']
},
'simulator:none': {
'CCFLAGS': ['-EL'],
'LINKFLAGS': ['-EL'],
Expand All @@ -554,6 +563,9 @@ SAMPLE_FLAGS = {
'mips_arch_variant:mips32r1': {
'CCFLAGS': ['-mips32', '-Wa,-mips32']
},
'mips_arch_variant:loongson': {
'CCFLAGS': ['-march=mips3', '-Wa,-march=mips3']
},
'library:static': {
'LINKFLAGS': ['-static', '-static-libgcc']
},
Expand Down Expand Up @@ -697,6 +709,9 @@ PREPARSER_FLAGS = {
'mips_arch_variant:mips32r2': {
'CPPDEFINES': ['_MIPS_ARCH_MIPS32R2']
},
'mips_arch_variant:loongson': {
'CPPDEFINES': ['_MIPS_ARCH_LOONGSON']
},
'simulator:none': {
'CCFLAGS': ['-EL'],
'LINKFLAGS': ['-EL'],
Expand All @@ -706,6 +721,9 @@ PREPARSER_FLAGS = {
'mips_arch_variant:mips32r1': {
'CCFLAGS': ['-mips32', '-Wa,-mips32']
},
'mips_arch_variant:loongson': {
'CCFLAGS': ['-march=mips3', '-Wa,-march=mips3']
},
'library:static': {
'LINKFLAGS': ['-static', '-static-libgcc']
},
Expand Down Expand Up @@ -1114,7 +1132,7 @@ SIMPLE_OPTIONS = {
'help': 'generate calling conventiont according to selected mips ABI'
},
'mips_arch_variant': {
'values': ['mips32r2', 'mips32r1'],
'values': ['mips32r2', 'mips32r1', 'loongson'],
'default': 'mips32r2',
'help': 'mips variant'
},
Expand Down
11 changes: 11 additions & 0 deletions build/common.gypi
Expand Up @@ -62,6 +62,9 @@
# Similar to the ARM hard float ABI but on MIPS.
'v8_use_mips_abi_hardfloat%': 'true',

# Default arch variant for MIPS.
'mips_arch_variant%': 'mips32r2',

'v8_enable_debugger_support%': 1,

'v8_enable_disassembler%': 0,
Expand Down Expand Up @@ -182,8 +185,13 @@
'cflags': ['-msoft-float'],
'ldflags': ['-msoft-float'],
}],
],
'conditions': [
['mips_arch_variant=="mips32r2"', {
'cflags': ['-mips32r2', '-Wa,-mips32r2'],
}],
['mips_arch_variant=="loongson"', {
'cflags': ['-mips3', '-Wa,-mips3'],
}, {
'cflags': ['-mips32', '-Wa,-mips32'],
}],
Expand All @@ -209,6 +217,9 @@
['mips_arch_variant=="mips32r2"', {
'defines': ['_MIPS_ARCH_MIPS32R2',],
}],
['mips_arch_variant=="loongson"', {
'defines': ['_MIPS_ARCH_LOONGSON',],
}],
# The MIPS assembler assumes the host is 32 bits,
# so force building 32-bit host tools.
['host_arch=="x64"', {
Expand Down
3 changes: 1 addition & 2 deletions build/mipsu.gypi
@@ -1,4 +1,4 @@
# Copyright 2011 the V8 project authors. All rights reserved.
# Copyright 2012 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:
Expand Down Expand Up @@ -29,6 +29,5 @@
'variables': {
'target_arch': 'ia32',
'v8_target_arch': 'mips',
'mips_arch_variant': 'mips32r2',
},
}
22 changes: 11 additions & 11 deletions src/mips/assembler-mips.cc
Expand Up @@ -30,7 +30,7 @@

// The original source code covered by the above license above has been
// modified significantly by Google Inc.
// Copyright 2011 the V8 project authors. All rights reserved.
// Copyright 2012 the V8 project authors. All rights reserved.


#include "v8.h"
Expand Down Expand Up @@ -1319,7 +1319,7 @@ void Assembler::srav(Register rd, Register rt, Register rs) {
void Assembler::rotr(Register rd, Register rt, uint16_t sa) {
// Should be called via MacroAssembler::Ror.
ASSERT(rd.is_valid() && rt.is_valid() && is_uint5(sa));
ASSERT(mips32r2);
ASSERT(kArchVariant == kMips32r2);
Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
| (rd.code() << kRdShift) | (sa << kSaShift) | SRL;
emit(instr);
Expand All @@ -1329,7 +1329,7 @@ void Assembler::rotr(Register rd, Register rt, uint16_t sa) {
void Assembler::rotrv(Register rd, Register rt, Register rs) {
// Should be called via MacroAssembler::Ror.
ASSERT(rd.is_valid() && rt.is_valid() && rs.is_valid() );
ASSERT(mips32r2);
ASSERT(kArchVariant == kMips32r2);
Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
| (rd.code() << kRdShift) | (1 << kSaShift) | SRLV;
emit(instr);
Expand Down Expand Up @@ -1604,15 +1604,15 @@ void Assembler::clz(Register rd, Register rs) {
void Assembler::ins_(Register rt, Register rs, uint16_t pos, uint16_t size) {
// Should be called via MacroAssembler::Ins.
// Ins instr has 'rt' field as dest, and two uint5: msb, lsb.
ASSERT(mips32r2);
ASSERT(kArchVariant == kMips32r2);
GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, INS);
}


void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
// Should be called via MacroAssembler::Ext.
// Ext instr has 'rt' field as dest, and two uint5: msb, lsb.
ASSERT(mips32r2);
ASSERT(kArchVariant == kMips32r2);
GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT);
}

Expand Down Expand Up @@ -1772,25 +1772,25 @@ void Assembler::ceil_w_d(FPURegister fd, FPURegister fs) {


void Assembler::cvt_l_s(FPURegister fd, FPURegister fs) {
ASSERT(mips32r2);
ASSERT(kArchVariant == kMips32r2);
GenInstrRegister(COP1, S, f0, fs, fd, CVT_L_S);
}


void Assembler::cvt_l_d(FPURegister fd, FPURegister fs) {
ASSERT(mips32r2);
ASSERT(kArchVariant == kMips32r2);
GenInstrRegister(COP1, D, f0, fs, fd, CVT_L_D);
}


void Assembler::trunc_l_s(FPURegister fd, FPURegister fs) {
ASSERT(mips32r2);
ASSERT(kArchVariant == kMips32r2);
GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_L_S);
}


void Assembler::trunc_l_d(FPURegister fd, FPURegister fs) {
ASSERT(mips32r2);
ASSERT(kArchVariant == kMips32r2);
GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_L_D);
}

Expand Down Expand Up @@ -1831,7 +1831,7 @@ void Assembler::cvt_s_w(FPURegister fd, FPURegister fs) {


void Assembler::cvt_s_l(FPURegister fd, FPURegister fs) {
ASSERT(mips32r2);
ASSERT(kArchVariant == kMips32r2);
GenInstrRegister(COP1, L, f0, fs, fd, CVT_S_L);
}

Expand All @@ -1847,7 +1847,7 @@ void Assembler::cvt_d_w(FPURegister fd, FPURegister fs) {


void Assembler::cvt_d_l(FPURegister fd, FPURegister fs) {
ASSERT(mips32r2);
ASSERT(kArchVariant == kMips32r2);
GenInstrRegister(COP1, L, f0, fs, fd, CVT_D_L);
}

Expand Down
28 changes: 14 additions & 14 deletions src/mips/code-stubs-mips.cc
Expand Up @@ -478,7 +478,7 @@ void ConvertToDoubleStub::Generate(MacroAssembler* masm) {
__ And(exponent, source_, Operand(HeapNumber::kSignMask));
// Subtract from 0 if source was negative.
__ subu(at, zero_reg, source_);
__ movn(source_, at, exponent);
__ Movn(source_, at, exponent);

// We have -1, 0 or 1, which we treat specially. Register source_ contains
// absolute value: it is either equal to 1 (special case of -1 and 1),
Expand All @@ -490,15 +490,15 @@ void ConvertToDoubleStub::Generate(MacroAssembler* masm) {
HeapNumber::kExponentBias << HeapNumber::kExponentShift;
// Safe to use 'at' as dest reg here.
__ Or(at, exponent, Operand(exponent_word_for_1));
__ movn(exponent, at, source_); // Write exp when source not 0.
__ Movn(exponent, at, source_); // Write exp when source not 0.
// 1, 0 and -1 all have 0 for the second word.
__ mov(mantissa, zero_reg);
__ Ret();

__ bind(&not_special);
// Count leading zeros.
// Gets the wrong answer for 0, but we already checked for that case above.
__ clz(zeros_, source_);
__ Clz(zeros_, source_);
// Compute exponent and or it into the exponent register.
// We use mantissa as a scratch register here.
__ li(mantissa, Operand(31 + HeapNumber::kExponentBias));
Expand Down Expand Up @@ -721,7 +721,7 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
// Get mantissa[51:20].

// Get the position of the first set bit.
__ clz(dst1, int_scratch);
__ Clz(dst1, int_scratch);
__ li(scratch2, 31);
__ Subu(dst1, scratch2, dst1);

Expand Down Expand Up @@ -1079,7 +1079,7 @@ void WriteInt32ToHeapNumberStub::Generate(MacroAssembler* masm) {
__ or_(scratch_, scratch_, sign_);
// Subtract from 0 if the value was negative.
__ subu(at, zero_reg, the_int_);
__ movn(the_int_, at, sign_);
__ Movn(the_int_, at, sign_);
// We should be masking the implict first digit of the mantissa away here,
// but it just ends up combining harmlessly with the last digit of the
// exponent that happens to be 1. The sign bit is 0 so we shift 10 to get
Expand Down Expand Up @@ -1750,15 +1750,15 @@ void CompareStub::Generate(MacroAssembler* masm) {
// Check if LESS condition is satisfied. If true, move conditionally
// result to v0.
__ c(OLT, D, f12, f14);
__ movt(v0, t0);
__ Movt(v0, t0);
// Use previous check to store conditionally to v0 oposite condition
// (GREATER). If rhs is equal to lhs, this will be corrected in next
// check.
__ movf(v0, t1);
__ Movf(v0, t1);
// Check if EQUAL condition is satisfied. If true, move conditionally
// result to v0.
__ c(EQ, D, f12, f14);
__ movt(v0, t2);
__ Movt(v0, t2);

__ Ret();

Expand Down Expand Up @@ -1899,7 +1899,7 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
__ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
__ And(at, at, Operand(1 << Map::kIsUndetectable));
// Undetectable -> false.
__ movn(tos_, zero_reg, at);
__ Movn(tos_, zero_reg, at);
__ Ret(ne, at, Operand(zero_reg));
}
}
Expand Down Expand Up @@ -1955,7 +1955,7 @@ void ToBooleanStub::CheckOddball(MacroAssembler* masm,
// The value of a root is never NULL, so we can avoid loading a non-null
// value into tos_ when we want to return 'true'.
if (!result) {
__ movz(tos_, zero_reg, at);
__ Movz(tos_, zero_reg, at);
}
__ Ret(eq, at, Operand(zero_reg));
}
Expand Down Expand Up @@ -5008,7 +5008,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ lw(t9, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset));
__ sra(a3, a0, 2); // a3 is 1 for ASCII, 0 for UC16 (used below).
__ lw(t1, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset));
__ movz(t9, t1, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset.
__ Movz(t9, t1, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset.

// Check that the irregexp code has been generated for the actual string
// encoding. If it has, the field contains a code object otherwise it contains
Expand Down Expand Up @@ -6037,7 +6037,7 @@ void StringHelper::GenerateHashGetHash(MacroAssembler* masm,

// if (hash == 0) hash = 27;
__ ori(at, zero_reg, StringHasher::kZeroHash);
__ movz(hash, at, hash);
__ Movz(hash, at, hash);
}


Expand Down Expand Up @@ -6327,7 +6327,7 @@ void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
__ Subu(scratch3, scratch1, Operand(scratch2));
Register length_delta = scratch3;
__ slt(scratch4, scratch2, scratch1);
__ movn(scratch1, scratch2, scratch4);
__ Movn(scratch1, scratch2, scratch4);
Register min_length = scratch1;
STATIC_ASSERT(kSmiTag == 0);
__ Branch(&compare_lengths, eq, min_length, Operand(zero_reg));
Expand Down Expand Up @@ -6485,7 +6485,7 @@ void StringAddStub::Generate(MacroAssembler* masm) {
__ lw(a2, FieldMemOperand(a0, String::kLengthOffset));
__ lw(a3, FieldMemOperand(a1, String::kLengthOffset));
__ mov(v0, a0); // Assume we'll return first string (from a0).
__ movz(v0, a1, a2); // If first is empty, return second (from a1).
__ Movz(v0, a1, a2); // If first is empty, return second (from a1).
__ slt(t4, zero_reg, a2); // if (a2 > 0) t4 = 1.
__ slt(t5, zero_reg, a3); // if (a3 > 0) t5 = 1.
__ and_(t4, t4, t5); // Branch if both strings were non-empty.
Expand Down
15 changes: 12 additions & 3 deletions src/mips/constants-mips.h
@@ -1,4 +1,4 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Copyright 2012 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:
Expand Down Expand Up @@ -39,11 +39,20 @@

#define UNSUPPORTED_MIPS() v8::internal::PrintF("Unsupported instruction.\n")

enum ArchVariants {
kMips32r2,
kMips32r1,
kLoongson
};

#ifdef _MIPS_ARCH_MIPS32R2
#define mips32r2 1
static const ArchVariants kArchVariant = kMips32r2;
#elif _MIPS_ARCH_LOONGSON
// The loongson flag refers to the LOONGSON architectures based on MIPS-III,
// which predates (and is a subset of) the mips32r2 and r1 architectures.
static const ArchVariants kArchVariant = kLoongson;
#else
#define mips32r2 0
static const ArchVariants kArchVariant = kMips32r1;
#endif


Expand Down

0 comments on commit 6fa2e17

Please sign in to comment.