зеркало из https://github.com/mozilla/gecko-dev.git
Bug 553962 - nanojit: finish adding get/set methods for CallInfo::_typesig. r=edwsmith.
--HG-- extra : convert_revision : cfbed237877f0939423d9c1ac591c0a7edb5b0c0
This commit is contained in:
Родитель
90226a86a3
Коммит
be9801c9c5
|
@ -337,24 +337,6 @@ private:
|
|||
void endFragment();
|
||||
};
|
||||
|
||||
// Meaning: arg 'm' of 'n' has type 'ty'.
|
||||
static int argMask(int ty, int m, int n)
|
||||
{
|
||||
// Order examples, from MSB to LSB:
|
||||
// - 3 args: 000 | 000 | 000 | 000 | 000 | arg1| arg2| arg3| ret
|
||||
// - 8 args: arg1| arg2| arg3| arg4| arg5| arg6| arg7| arg8| ret
|
||||
// If the mask encoding reversed the arg order the 'n' parameter wouldn't
|
||||
// be necessary, as argN would always be in the same place in the
|
||||
// bitfield.
|
||||
return ty << ((1 + n - m) * ARGTYPE_SHIFT);
|
||||
}
|
||||
|
||||
// Return value has type 'ty'.
|
||||
static int retMask(int ty)
|
||||
{
|
||||
return ty;
|
||||
}
|
||||
|
||||
// 'sin' is overloaded on some platforms, so taking its address
|
||||
// doesn't quite work. Provide a do-nothing function here
|
||||
// that's not overloaded.
|
||||
|
@ -364,10 +346,10 @@ double sinFn(double d) {
|
|||
#define sin sinFn
|
||||
|
||||
Function functions[] = {
|
||||
FN(puts, argMask(ARGTYPE_P, 1, 1) | retMask(ARGTYPE_I)),
|
||||
FN(sin, argMask(ARGTYPE_D, 1, 1) | retMask(ARGTYPE_D)),
|
||||
FN(malloc, argMask(ARGTYPE_P, 1, 1) | retMask(ARGTYPE_P)),
|
||||
FN(free, argMask(ARGTYPE_P, 1, 1) | retMask(ARGTYPE_V))
|
||||
FN(puts, CallInfo::typeSig1(ARGTYPE_I, ARGTYPE_P)),
|
||||
FN(sin, CallInfo::typeSig1(ARGTYPE_D, ARGTYPE_D)),
|
||||
FN(malloc, CallInfo::typeSig1(ARGTYPE_P, ARGTYPE_P)),
|
||||
FN(free, CallInfo::typeSig1(ARGTYPE_V, ARGTYPE_P)),
|
||||
};
|
||||
|
||||
template<typename out, typename in> out
|
||||
|
@ -687,32 +669,28 @@ FragmentAssembler::assemble_call(const string &op)
|
|||
} else {
|
||||
// User-defined function: infer CallInfo details (ABI, arg types, ret
|
||||
// type) from the call site.
|
||||
int ty;
|
||||
|
||||
ci->_abi = _abi;
|
||||
|
||||
ci->_typesig = 0;
|
||||
size_t argc = mTokens.size();
|
||||
ArgType argTypes[MAXARGS];
|
||||
for (size_t i = 0; i < argc; ++i) {
|
||||
NanoAssert(i < MAXARGS); // should give a useful error msg if this fails
|
||||
args[i] = ref(mTokens[mTokens.size() - (i+1)]);
|
||||
if (args[i]->isD()) ty = ARGTYPE_D;
|
||||
if (args[i]->isD()) argTypes[i] = ARGTYPE_D;
|
||||
#ifdef NANOJIT_64BIT
|
||||
else if (args[i]->isQ()) ty = ARGTYPE_Q;
|
||||
else if (args[i]->isQ()) argTypes[i] = ARGTYPE_Q;
|
||||
#endif
|
||||
else ty = ARGTYPE_I;
|
||||
// Nb: i+1 because argMask() uses 1-based arg counting.
|
||||
ci->_typesig |= argMask(ty, i+1, argc);
|
||||
else argTypes[i] = ARGTYPE_I;
|
||||
}
|
||||
|
||||
// Select return type from opcode.
|
||||
ty = 0;
|
||||
if (mOpcode == LIR_calli) ty = ARGTYPE_I;
|
||||
else if (mOpcode == LIR_calld) ty = ARGTYPE_D;
|
||||
ArgType retType = ARGTYPE_V;
|
||||
if (mOpcode == LIR_calli) retType = ARGTYPE_I;
|
||||
else if (mOpcode == LIR_calld) retType = ARGTYPE_D;
|
||||
#ifdef NANOJIT_64BIT
|
||||
else if (mOpcode == LIR_callq) ty = ARGTYPE_Q;
|
||||
else if (mOpcode == LIR_callq) retType = ARGTYPE_Q;
|
||||
#endif
|
||||
else nyi("callh");
|
||||
ci->_typesig |= retMask(ty);
|
||||
ci->_typesig = CallInfo::typeSigN(retType, argc, argTypes);
|
||||
}
|
||||
|
||||
return mLir->insCall(ci, args);
|
||||
|
@ -1283,52 +1261,23 @@ static void f_V_IQF(int32_t, uint64_t, double)
|
|||
}
|
||||
#endif
|
||||
|
||||
const CallInfo ci_I_I1 = CI(f_I_I1, argMask(ARGTYPE_I, 1, 1) |
|
||||
retMask(ARGTYPE_I));
|
||||
|
||||
const CallInfo ci_I_I6 = CI(f_I_I6, argMask(ARGTYPE_I, 1, 6) |
|
||||
argMask(ARGTYPE_I, 2, 6) |
|
||||
argMask(ARGTYPE_I, 3, 6) |
|
||||
argMask(ARGTYPE_I, 4, 6) |
|
||||
argMask(ARGTYPE_I, 5, 6) |
|
||||
argMask(ARGTYPE_I, 6, 6) |
|
||||
retMask(ARGTYPE_I));
|
||||
const CallInfo ci_I_I1 = CI(f_I_I1, CallInfo::typeSig1(ARGTYPE_I, ARGTYPE_I));
|
||||
const CallInfo ci_I_I6 = CI(f_I_I6, CallInfo::typeSig6(ARGTYPE_I, ARGTYPE_I, ARGTYPE_I, ARGTYPE_I,
|
||||
ARGTYPE_I, ARGTYPE_I, ARGTYPE_I));
|
||||
|
||||
#ifdef NANOJIT_64BIT
|
||||
const CallInfo ci_Q_Q2 = CI(f_Q_Q2, argMask(ARGTYPE_Q, 1, 2) |
|
||||
argMask(ARGTYPE_Q, 2, 2) |
|
||||
retMask(ARGTYPE_Q));
|
||||
|
||||
const CallInfo ci_Q_Q7 = CI(f_Q_Q7, argMask(ARGTYPE_Q, 1, 7) |
|
||||
argMask(ARGTYPE_Q, 2, 7) |
|
||||
argMask(ARGTYPE_Q, 3, 7) |
|
||||
argMask(ARGTYPE_Q, 4, 7) |
|
||||
argMask(ARGTYPE_Q, 5, 7) |
|
||||
argMask(ARGTYPE_Q, 6, 7) |
|
||||
argMask(ARGTYPE_Q, 7, 7) |
|
||||
retMask(ARGTYPE_Q));
|
||||
const CallInfo ci_Q_Q2 = CI(f_Q_Q2, CallInfo::typeSig2(ARGTYPE_Q, ARGTYPE_Q, ARGTYPE_Q));
|
||||
const CallInfo ci_Q_Q7 = CI(f_Q_Q7, CallInfo::typeSig7(ARGTYPE_Q, ARGTYPE_Q, ARGTYPE_Q, ARGTYPE_Q,
|
||||
ARGTYPE_Q, ARGTYPE_Q, ARGTYPE_Q, ARGTYPE_Q));
|
||||
#endif
|
||||
|
||||
const CallInfo ci_F_F3 = CI(f_F_F3, argMask(ARGTYPE_D, 1, 3) |
|
||||
argMask(ARGTYPE_D, 2, 3) |
|
||||
argMask(ARGTYPE_D, 3, 3) |
|
||||
retMask(ARGTYPE_D));
|
||||
|
||||
const CallInfo ci_F_F8 = CI(f_F_F8, argMask(ARGTYPE_D, 1, 8) |
|
||||
argMask(ARGTYPE_D, 2, 8) |
|
||||
argMask(ARGTYPE_D, 3, 8) |
|
||||
argMask(ARGTYPE_D, 4, 8) |
|
||||
argMask(ARGTYPE_D, 5, 8) |
|
||||
argMask(ARGTYPE_D, 6, 8) |
|
||||
argMask(ARGTYPE_D, 7, 8) |
|
||||
argMask(ARGTYPE_D, 8, 8) |
|
||||
retMask(ARGTYPE_D));
|
||||
const CallInfo ci_F_F3 = CI(f_F_F3, CallInfo::typeSig3(ARGTYPE_D, ARGTYPE_D, ARGTYPE_D, ARGTYPE_D));
|
||||
const CallInfo ci_F_F8 = CI(f_F_F8, CallInfo::typeSig8(ARGTYPE_D, ARGTYPE_D, ARGTYPE_D, ARGTYPE_D,
|
||||
ARGTYPE_D, ARGTYPE_D, ARGTYPE_D, ARGTYPE_D,
|
||||
ARGTYPE_D));
|
||||
|
||||
#ifdef NANOJIT_64BIT
|
||||
const CallInfo ci_V_IQF = CI(f_V_IQF, argMask(ARGTYPE_I, 1, 3) |
|
||||
argMask(ARGTYPE_Q, 2, 3) |
|
||||
argMask(ARGTYPE_D, 3, 3) |
|
||||
retMask(ARGTYPE_V));
|
||||
const CallInfo ci_V_IQF = CI(f_V_IQF, CallInfo::typeSig3(ARGTYPE_V, ARGTYPE_I, ARGTYPE_Q, ARGTYPE_D));
|
||||
#endif
|
||||
|
||||
// Generate a random block containing nIns instructions, plus a few more
|
||||
|
|
|
@ -85,10 +85,10 @@ namespace nanojit
|
|||
{
|
||||
uint32_t argc = 0;
|
||||
uint32_t argt = _typesig;
|
||||
argt >>= ARGTYPE_SHIFT; // remove retType
|
||||
argt >>= TYPESIG_FIELDSZB; // remove retType
|
||||
while (argt) {
|
||||
argc++;
|
||||
argt >>= ARGTYPE_SHIFT;
|
||||
argt >>= TYPESIG_FIELDSZB;
|
||||
}
|
||||
return argc;
|
||||
}
|
||||
|
@ -97,12 +97,12 @@ namespace nanojit
|
|||
{
|
||||
uint32_t argc = 0;
|
||||
uint32_t argt = _typesig;
|
||||
argt >>= ARGTYPE_SHIFT; // remove retType
|
||||
argt >>= TYPESIG_FIELDSZB; // remove retType
|
||||
while (argt) {
|
||||
ArgType a = ArgType(argt & ARGTYPE_MASK);
|
||||
ArgType a = ArgType(argt & TYPESIG_FIELDMASK);
|
||||
if (a == ARGTYPE_I || a == ARGTYPE_UI)
|
||||
argc++;
|
||||
argt >>= ARGTYPE_SHIFT;
|
||||
argt >>= TYPESIG_FIELDSZB;
|
||||
}
|
||||
return argc;
|
||||
}
|
||||
|
@ -111,12 +111,12 @@ namespace nanojit
|
|||
{
|
||||
uint32_t argc = 0;
|
||||
uint32_t argt = _typesig;
|
||||
argt >>= ARGTYPE_SHIFT; // remove retType
|
||||
argt >>= TYPESIG_FIELDSZB; // remove retType
|
||||
while (argt) {
|
||||
ArgType a = ArgType(argt & ARGTYPE_MASK);
|
||||
ArgType a = ArgType(argt & TYPESIG_FIELDMASK);
|
||||
argTypes[argc] = a;
|
||||
argc++;
|
||||
argt >>= ARGTYPE_SHIFT;
|
||||
argt >>= TYPESIG_FIELDSZB;
|
||||
}
|
||||
return argc;
|
||||
}
|
||||
|
@ -2512,11 +2512,11 @@ namespace nanojit
|
|||
static int32_t FASTCALL led(double a, double b) { return a <= b; }
|
||||
static int32_t FASTCALL ged(double a, double b) { return a >= b; }
|
||||
|
||||
#define SIG_D_I (ARGTYPE_D | ARGTYPE_I << ARGTYPE_SHIFT*1)
|
||||
#define SIG_D_UI (ARGTYPE_D | ARGTYPE_UI << ARGTYPE_SHIFT*1)
|
||||
#define SIG_D_D (ARGTYPE_D | ARGTYPE_D << ARGTYPE_SHIFT*1)
|
||||
#define SIG_D_DD (ARGTYPE_D | ARGTYPE_D << ARGTYPE_SHIFT*1 | ARGTYPE_D << ARGTYPE_SHIFT*2)
|
||||
#define SIG_B_DD (ARGTYPE_B | ARGTYPE_D << ARGTYPE_SHIFT*1 | ARGTYPE_D << ARGTYPE_SHIFT*2)
|
||||
#define SIG_D_I typeSig1(ARGTYPE_D, ARGTYPE_I)
|
||||
#define SIG_D_UI typeSig1(ARGTYPE_D, ARGTYPE_UI)
|
||||
#define SIG_D_D typeSig1(ARGTYPE_D, ARGTYPE_D)
|
||||
#define SIG_D_DD typeSig2(ARGTYPE_D, ARGTYPE_D, ARGTYPE_D)
|
||||
#define SIG_B_DD typeSig2(ARGTYPE_B, ARGTYPE_D, ARGTYPE_D)
|
||||
|
||||
#define SF_CALLINFO(name, typesig) \
|
||||
static const CallInfo name##_ci = \
|
||||
|
|
|
@ -176,10 +176,6 @@ namespace nanojit
|
|||
ARGTYPE_B = ARGTYPE_I // bool
|
||||
};
|
||||
|
||||
// In _typesig, each entry is three bits.
|
||||
static const int ARGTYPE_SHIFT = 3;
|
||||
static const int ARGTYPE_MASK = 0x7;
|
||||
|
||||
enum IndirectCall {
|
||||
CALL_INDIRECT = 0
|
||||
};
|
||||
|
@ -315,9 +311,13 @@ namespace nanojit
|
|||
static const AccSet ACC_LOAD_ANY = ACC_ALL; // synonym
|
||||
static const AccSet ACC_STORE_ANY = ACC_ALL_STORABLE; // synonym
|
||||
|
||||
|
||||
struct CallInfo
|
||||
{
|
||||
private:
|
||||
// In CallInfo::_typesig, each entry is three bits.
|
||||
static const int TYPESIG_FIELDSZB = 3;
|
||||
static const int TYPESIG_FIELDMASK = 7;
|
||||
|
||||
public:
|
||||
uintptr_t _address;
|
||||
|
@ -327,13 +327,55 @@ namespace nanojit
|
|||
AccSet _storeAccSet; // access regions stored by the function
|
||||
verbose_only ( const char* _name; )
|
||||
|
||||
// The following encode 'r func()' through to 'r func(a1, a2, a3, a4, a5, a6, a7, a8)'.
|
||||
static inline uint32_t typeSig0(ArgType r) {
|
||||
return r;
|
||||
}
|
||||
static inline uint32_t typeSig1(ArgType r, ArgType a1) {
|
||||
return a1 << TYPESIG_FIELDSZB*1 | typeSig0(r);
|
||||
}
|
||||
static inline uint32_t typeSig2(ArgType r, ArgType a1, ArgType a2) {
|
||||
return a1 << TYPESIG_FIELDSZB*2 | typeSig1(r, a2);
|
||||
}
|
||||
static inline uint32_t typeSig3(ArgType r, ArgType a1, ArgType a2, ArgType a3) {
|
||||
return a1 << TYPESIG_FIELDSZB*3 | typeSig2(r, a2, a3);
|
||||
}
|
||||
static inline uint32_t typeSig4(ArgType r, ArgType a1, ArgType a2, ArgType a3, ArgType a4) {
|
||||
return a1 << TYPESIG_FIELDSZB*4 | typeSig3(r, a2, a3, a4);
|
||||
}
|
||||
static inline uint32_t typeSig5(ArgType r, ArgType a1, ArgType a2, ArgType a3,
|
||||
ArgType a4, ArgType a5) {
|
||||
return a1 << TYPESIG_FIELDSZB*5 | typeSig4(r, a2, a3, a4, a5);
|
||||
}
|
||||
static inline uint32_t typeSig6(ArgType r, ArgType a1, ArgType a2, ArgType a3,
|
||||
ArgType a4, ArgType a5, ArgType a6) {
|
||||
return a1 << TYPESIG_FIELDSZB*6 | typeSig5(r, a2, a3, a4, a5, a6);
|
||||
}
|
||||
static inline uint32_t typeSig7(ArgType r, ArgType a1, ArgType a2, ArgType a3,
|
||||
ArgType a4, ArgType a5, ArgType a6, ArgType a7) {
|
||||
return a1 << TYPESIG_FIELDSZB*7 | typeSig6(r, a2, a3, a4, a5, a6, a7);
|
||||
}
|
||||
static inline uint32_t typeSig8(ArgType r, ArgType a1, ArgType a2, ArgType a3, ArgType a4,
|
||||
ArgType a5, ArgType a6, ArgType a7, ArgType a8) {
|
||||
return a1 << TYPESIG_FIELDSZB*8 | typeSig7(r, a2, a3, a4, a5, a6, a7, a8);
|
||||
}
|
||||
// Encode 'r func(a1, ..., aN))'
|
||||
static inline uint32_t typeSigN(ArgType r, int N, ArgType a[]) {
|
||||
uint32_t typesig = r;
|
||||
for (int i = 0; i < N; i++) {
|
||||
typesig |= a[i] << TYPESIG_FIELDSZB*(N-i);
|
||||
}
|
||||
return typesig;
|
||||
}
|
||||
|
||||
uint32_t count_args() const;
|
||||
uint32_t count_int32_args() const;
|
||||
// Nb: uses right-to-left order, eg. sizes[0] is the size of the right-most arg.
|
||||
// XXX: See bug 525815 for fixing this.
|
||||
uint32_t getArgTypes(ArgType* types) const;
|
||||
|
||||
inline ArgType returnType() const {
|
||||
return ArgType(_typesig & ARGTYPE_MASK);
|
||||
return ArgType(_typesig & TYPESIG_FIELDMASK);
|
||||
}
|
||||
|
||||
inline bool isIndirect() const {
|
||||
|
|
Загрузка…
Ссылка в новой задаче