Bug 553962 - nanojit: finish adding get/set methods for CallInfo::_typesig. r=edwsmith.

--HG--
extra : convert_revision : cfbed237877f0939423d9c1ac591c0a7edb5b0c0
This commit is contained in:
Nicholas Nethercote 2010-07-04 19:39:09 -07:00
Родитель 90226a86a3
Коммит be9801c9c5
3 изменённых файлов: 86 добавлений и 95 удалений

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

@ -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 = \

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

@ -173,13 +173,9 @@ namespace nanojit
// aliases
ARGTYPE_P = PTR_SIZE(ARGTYPE_I, ARGTYPE_Q), // pointer
ARGTYPE_B = ARGTYPE_I // bool
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 {