mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 595728 - nanojit: clarify semantics of shift operations. r=edwsmith.
--HG-- extra : convert_revision : 2a75fed5283f0efb625b10d20db007ad6bfe849a
This commit is contained in:
parent
9e20f0f9b8
commit
ced06e86bf
@ -150,7 +150,8 @@ void ValidateWriter::checkAccSet(LOpcode op, LIns* base, int32_t disp, AccSet ac
|
||||
#endif
|
||||
|
||||
typedef int32_t (FASTCALL *RetInt)();
|
||||
typedef double (FASTCALL *RetFloat)();
|
||||
typedef int64_t (FASTCALL *RetQuad)();
|
||||
typedef double (FASTCALL *RetDouble)();
|
||||
typedef GuardRecord* (FASTCALL *RetGuard)();
|
||||
|
||||
struct Function {
|
||||
@ -159,9 +160,12 @@ struct Function {
|
||||
};
|
||||
|
||||
enum ReturnType {
|
||||
RT_INT32 = 1,
|
||||
RT_FLOAT = 2,
|
||||
RT_GUARD = 4
|
||||
RT_INT = 1,
|
||||
#ifdef NANOJIT_64BIT
|
||||
RT_QUAD = 2,
|
||||
#endif
|
||||
RT_DOUBLE = 4,
|
||||
RT_GUARD = 8
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -262,8 +266,11 @@ private:
|
||||
class LirasmFragment {
|
||||
public:
|
||||
union {
|
||||
RetFloat rfloat;
|
||||
RetInt rint;
|
||||
#ifdef NANOJIT_64BIT
|
||||
RetQuad rquad;
|
||||
#endif
|
||||
RetDouble rdouble;
|
||||
RetGuard rguard;
|
||||
};
|
||||
ReturnType mReturnType;
|
||||
@ -817,9 +824,14 @@ FragmentAssembler::endFragment()
|
||||
if (mReturnTypeBits == 0) {
|
||||
cerr << "warning: no return type in fragment '"
|
||||
<< mFragName << "'" << endl;
|
||||
}
|
||||
if (mReturnTypeBits != RT_INT32 && mReturnTypeBits != RT_FLOAT &&
|
||||
mReturnTypeBits != RT_GUARD) {
|
||||
|
||||
} else if (mReturnTypeBits != RT_INT &&
|
||||
#ifdef NANOJIT_64BIT
|
||||
mReturnTypeBits != RT_QUAD &&
|
||||
#endif
|
||||
mReturnTypeBits != RT_DOUBLE &&
|
||||
mReturnTypeBits != RT_GUARD)
|
||||
{
|
||||
cerr << "warning: multiple return types in fragment '"
|
||||
<< mFragName << "'" << endl;
|
||||
}
|
||||
@ -847,17 +859,26 @@ FragmentAssembler::endFragment()
|
||||
f = &mParent.mFragments[mFragName];
|
||||
|
||||
switch (mReturnTypeBits) {
|
||||
case RT_INT:
|
||||
f->rint = (RetInt)((uintptr_t)mFragment->code());
|
||||
f->mReturnType = RT_INT;
|
||||
break;
|
||||
#ifdef NANOJIT_64BIT
|
||||
case RT_QUAD:
|
||||
f->rquad = (RetQuad)((uintptr_t)mFragment->code());
|
||||
f->mReturnType = RT_QUAD;
|
||||
break;
|
||||
#endif
|
||||
case RT_DOUBLE:
|
||||
f->rdouble = (RetDouble)((uintptr_t)mFragment->code());
|
||||
f->mReturnType = RT_DOUBLE;
|
||||
break;
|
||||
case RT_GUARD:
|
||||
f->rguard = (RetGuard)((uintptr_t)mFragment->code());
|
||||
f->mReturnType = RT_GUARD;
|
||||
break;
|
||||
case RT_FLOAT:
|
||||
f->rfloat = (RetFloat)((uintptr_t)mFragment->code());
|
||||
f->mReturnType = RT_FLOAT;
|
||||
break;
|
||||
default:
|
||||
f->rint = (RetInt)((uintptr_t)mFragment->code());
|
||||
f->mReturnType = RT_INT32;
|
||||
NanoAssert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1158,11 +1179,17 @@ FragmentAssembler::assembleFragment(LirTokenStream &in, bool implicitBegin, cons
|
||||
break;
|
||||
|
||||
case LIR_reti:
|
||||
ins = assemble_ret(RT_INT32);
|
||||
ins = assemble_ret(RT_INT);
|
||||
break;
|
||||
|
||||
#ifdef NANOJIT_64BIT
|
||||
case LIR_retq:
|
||||
ins = assemble_ret(RT_QUAD);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case LIR_retd:
|
||||
ins = assemble_ret(RT_FLOAT);
|
||||
ins = assemble_ret(RT_DOUBLE);
|
||||
break;
|
||||
|
||||
case LIR_label:
|
||||
@ -1176,7 +1203,6 @@ FragmentAssembler::assembleFragment(LirTokenStream &in, bool implicitBegin, cons
|
||||
case LIR_line:
|
||||
case LIR_xtbl:
|
||||
case LIR_jtbl:
|
||||
CASE64(LIR_retq:)
|
||||
nyi(op);
|
||||
break;
|
||||
|
||||
@ -2019,7 +2045,7 @@ FragmentAssembler::assembleRandomFragment(int nIns)
|
||||
delete[] classGenerator;
|
||||
|
||||
// Return 0.
|
||||
mReturnTypeBits |= RT_INT32;
|
||||
mReturnTypeBits |= RT_INT;
|
||||
mLir->ins1(LIR_reti, mLir->insImmI(0));
|
||||
|
||||
endFragment();
|
||||
@ -2072,8 +2098,8 @@ Lirasm::lookupFunction(const string &name, CallInfo *&ci)
|
||||
Fragments::const_iterator func = mFragments.find(name);
|
||||
if (func != mFragments.end()) {
|
||||
// The ABI, arg types and ret type will be overridden by the caller.
|
||||
if (func->second.mReturnType == RT_FLOAT) {
|
||||
CallInfo target = {(uintptr_t) func->second.rfloat,
|
||||
if (func->second.mReturnType == RT_DOUBLE) {
|
||||
CallInfo target = {(uintptr_t) func->second.rdouble,
|
||||
0, ABI_FASTCALL, /*isPure*/0, ACCSET_STORE_ANY
|
||||
verbose_only(, func->first.c_str()) };
|
||||
*ci = target;
|
||||
@ -2339,20 +2365,24 @@ main(int argc, char **argv)
|
||||
if (i == lasm.mFragments.end())
|
||||
errMsgAndQuit(opts.progname, "error: at least one fragment must be named 'main'");
|
||||
switch (i->second.mReturnType) {
|
||||
case RT_FLOAT:
|
||||
{
|
||||
double res = i->second.rfloat();
|
||||
cout << "Output is: " << res << endl;
|
||||
break;
|
||||
}
|
||||
case RT_INT32:
|
||||
{
|
||||
case RT_INT: {
|
||||
int res = i->second.rint();
|
||||
cout << "Output is: " << res << endl;
|
||||
break;
|
||||
}
|
||||
case RT_GUARD:
|
||||
{
|
||||
#ifdef NANOJIT_64BIT
|
||||
case RT_QUAD: {
|
||||
int res = i->second.rquad();
|
||||
cout << "Output is: " << res << endl;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case RT_DOUBLE: {
|
||||
double res = i->second.rdouble();
|
||||
cout << "Output is: " << res << endl;
|
||||
break;
|
||||
}
|
||||
case RT_GUARD: {
|
||||
LasmSideExit *ls = (LasmSideExit*) i->second.rguard()->exit;
|
||||
cout << "Exited block on line: " << ls->line << endl;
|
||||
break;
|
||||
|
@ -42,9 +42,6 @@ do
|
||||
runtest $infile
|
||||
done
|
||||
|
||||
runtest "--random 1000000"
|
||||
runtest "--random 1000000 --optimize"
|
||||
|
||||
# ---- Platform-specific tests and configurations. ----
|
||||
|
||||
# 64-bit platforms
|
||||
@ -102,5 +99,10 @@ then
|
||||
runtest "--random 10000 --optimize --arch 5 --novfp"
|
||||
fi
|
||||
|
||||
# ---- Randomized tests, they are run last because they are slow ----
|
||||
|
||||
runtest "--random 1000000"
|
||||
runtest "--random 1000000 --optimize"
|
||||
|
||||
rm testoutput.txt
|
||||
|
||||
|
@ -263,6 +263,9 @@ OP___(andi, 85, Op2, I, 1) // bitwise-AND int
|
||||
OP___(ori, 86, Op2, I, 1) // bitwise-OR int
|
||||
OP___(xori, 87, Op2, I, 1) // bitwise-XOR int
|
||||
|
||||
// For all three integer shift operations, only the bottom five bits of the
|
||||
// second operand are used, and they are treated as unsigned. This matches
|
||||
// x86 semantics.
|
||||
OP___(lshi, 88, Op2, I, 1) // left shift int
|
||||
OP___(rshi, 89, Op2, I, 1) // right shift int (>>)
|
||||
OP___(rshui, 90, Op2, I, 1) // right shift unsigned int (>>>)
|
||||
@ -274,6 +277,9 @@ OP_64(andq, 93, Op2, Q, 1) // bitwise-AND quad
|
||||
OP_64(orq, 94, Op2, Q, 1) // bitwise-OR quad
|
||||
OP_64(xorq, 95, Op2, Q, 1) // bitwise-XOR quad
|
||||
|
||||
// For all three quad shift operations, only the bottom six bits of the
|
||||
// second operand are used, and they are treated as unsigned. This matches
|
||||
// x86-64 semantics.
|
||||
OP_64(lshq, 96, Op2, Q, 1) // left shift quad; 2nd operand is an int
|
||||
OP_64(rshq, 97, Op2, Q, 1) // right shift quad; 2nd operand is an int
|
||||
OP_64(rshuq, 98, Op2, Q, 1) // right shift unsigned quad; 2nd operand is an int
|
||||
|
Loading…
Reference in New Issue
Block a user