mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-10-03 06:55:41 +00:00
intel specific fixes + gstate cleanup (#532)
* fix non-PPC codepath: branch32 to branchPtr * fix register structure access on x86 * save graphic context, tweak calculation * M1499198 * M1499198 * use old SSE Int32x4 load instead of missing Simd which were too difficult to backport, remove error
This commit is contained in:
parent
f059d57c07
commit
e4c0873499
@ -26,6 +26,14 @@
|
|||||||
#include "jit/Disassembler.h"
|
#include "jit/Disassembler.h"
|
||||||
#include "vm/Runtime.h"
|
#include "vm/Runtime.h"
|
||||||
|
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
#ifndef __ppc__
|
||||||
|
#include <sys/ucontext.h>
|
||||||
|
#include <mach/mach_types.h>
|
||||||
|
#include <mach/thread_status.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace js;
|
using namespace js;
|
||||||
using namespace js::jit;
|
using namespace js::jit;
|
||||||
|
|
||||||
@ -202,9 +210,9 @@ class AutoSetHandlingSignal
|
|||||||
# define R15_sig(p) ((p)->uc_mcontext.mc_r15)
|
# define R15_sig(p) ((p)->uc_mcontext.mc_r15)
|
||||||
# endif
|
# endif
|
||||||
#elif defined(XP_DARWIN)
|
#elif defined(XP_DARWIN)
|
||||||
# define EIP_sig(p) ((p)->uc_mcontext->__ss.__eip)
|
# define EIP_sig(p) ((p)->uc_mcontext->ss.eip)
|
||||||
# define RIP_sig(p) ((p)->uc_mcontext->__ss.__rip)
|
# define RIP_sig(p) ((p)->uc_mcontext->ss.rip)
|
||||||
# define R15_sig(p) ((p)->uc_mcontext->__ss.__pc)
|
# define R15_sig(p) ((p)->uc_mcontext->ss.pc)
|
||||||
#else
|
#else
|
||||||
# error "Don't know how to read/write to the thread state via the mcontext_t."
|
# error "Don't know how to read/write to the thread state via the mcontext_t."
|
||||||
#endif
|
#endif
|
||||||
|
@ -800,7 +800,7 @@ NativeRegExpMacroAssembler::CheckNotBackReference(int start_reg, Label* on_no_ma
|
|||||||
|
|
||||||
#ifndef JS_CODEGEN_PPC_OSX
|
#ifndef JS_CODEGEN_PPC_OSX
|
||||||
// Fail on partial or illegal capture (start of capture after end of capture).
|
// Fail on partial or illegal capture (start of capture after end of capture).
|
||||||
masm.branch32(Assembler::LessThan, temp0, ImmWord(0), BranchOrBacktrack(on_no_match));
|
masm.branchPtr(Assembler::LessThan, temp0, ImmWord(0), BranchOrBacktrack(on_no_match));
|
||||||
// Succeed on empty capture (including no capture).
|
// Succeed on empty capture (including no capture).
|
||||||
masm.branchPtr(Assembler::Equal, temp0, ImmWord(0), &fallthrough);
|
masm.branchPtr(Assembler::Equal, temp0, ImmWord(0), &fallthrough);
|
||||||
#else
|
#else
|
||||||
@ -811,7 +811,11 @@ NativeRegExpMacroAssembler::CheckNotBackReference(int start_reg, Label* on_no_ma
|
|||||||
// Check that there are sufficient characters left in the input.
|
// Check that there are sufficient characters left in the input.
|
||||||
masm.movePtr(current_position, temp1);
|
masm.movePtr(current_position, temp1);
|
||||||
masm.addPtr(temp0, temp1);
|
masm.addPtr(temp0, temp1);
|
||||||
|
#ifndef JS_CODEGEN_PPC_OSX
|
||||||
|
masm.branchPtr(Assembler::GreaterThan, temp1, ImmWord(0), BranchOrBacktrack(on_no_match));
|
||||||
|
#else
|
||||||
masm.branch32(Assembler::GreaterThan, temp1, ImmWord(0), BranchOrBacktrack(on_no_match));
|
masm.branch32(Assembler::GreaterThan, temp1, ImmWord(0), BranchOrBacktrack(on_no_match));
|
||||||
|
#endif
|
||||||
|
|
||||||
// Save register to make it available below.
|
// Save register to make it available below.
|
||||||
masm.push(backtrack_stack_pointer);
|
masm.push(backtrack_stack_pointer);
|
||||||
@ -895,7 +899,7 @@ NativeRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(int start_reg, Label
|
|||||||
// The length of a capture should not be negative. This can only happen
|
// The length of a capture should not be negative. This can only happen
|
||||||
// if the end of the capture is unrecorded, or at a point earlier than
|
// if the end of the capture is unrecorded, or at a point earlier than
|
||||||
// the start of the capture.
|
// the start of the capture.
|
||||||
masm.branch32(Assembler::LessThan, temp1, ImmWord(0), BranchOrBacktrack(on_no_match));
|
masm.branchPtr(Assembler::LessThan, temp1, ImmWord(0), BranchOrBacktrack(on_no_match));
|
||||||
|
|
||||||
// If length is zero, either the capture is empty or it is completely
|
// If length is zero, either the capture is empty or it is completely
|
||||||
// uncaptured. In either case succeed immediately.
|
// uncaptured. In either case succeed immediately.
|
||||||
@ -908,7 +912,11 @@ NativeRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(int start_reg, Label
|
|||||||
// Check that there are sufficient characters left in the input.
|
// Check that there are sufficient characters left in the input.
|
||||||
masm.movePtr(current_position, temp0);
|
masm.movePtr(current_position, temp0);
|
||||||
masm.addPtr(temp1, temp0);
|
masm.addPtr(temp1, temp0);
|
||||||
|
#ifndef JS_CODEGEN_PPC_OSX
|
||||||
|
masm.branchPtr(Assembler::GreaterThan, temp0, ImmWord(0), BranchOrBacktrack(on_no_match));
|
||||||
|
#else
|
||||||
masm.branch32(Assembler::GreaterThan, temp0, ImmWord(0), BranchOrBacktrack(on_no_match));
|
masm.branch32(Assembler::GreaterThan, temp0, ImmWord(0), BranchOrBacktrack(on_no_match));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mode_ == ASCII) {
|
if (mode_ == ASCII) {
|
||||||
Label success, fail;
|
Label success, fail;
|
||||||
@ -1488,8 +1496,13 @@ void
|
|||||||
NativeRegExpMacroAssembler::CheckPosition(int cp_offset, Label* on_outside_input)
|
NativeRegExpMacroAssembler::CheckPosition(int cp_offset, Label* on_outside_input)
|
||||||
{
|
{
|
||||||
JitSpew(SPEW_PREFIX "CheckPosition(%d)", cp_offset);
|
JitSpew(SPEW_PREFIX "CheckPosition(%d)", cp_offset);
|
||||||
|
#ifndef JS_CODEGEN_PPC_OSX
|
||||||
|
masm.branchPtr(Assembler::GreaterThanOrEqual, current_position,
|
||||||
|
ImmWord(-cp_offset * char_size()), BranchOrBacktrack(on_outside_input));
|
||||||
|
#else
|
||||||
masm.branch32(Assembler::GreaterThanOrEqual, current_position,
|
masm.branch32(Assembler::GreaterThanOrEqual, current_position,
|
||||||
ImmWord(-cp_offset * char_size()), BranchOrBacktrack(on_outside_input));
|
ImmWord(-cp_offset * char_size()), BranchOrBacktrack(on_outside_input));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Label*
|
Label*
|
||||||
|
@ -398,20 +398,11 @@ class Assembler : public AssemblerX86Shared
|
|||||||
MOZ_ASSERT(dest.size() == 16);
|
MOZ_ASSERT(dest.size() == 16);
|
||||||
masm.vhaddpd_rr(src.encoding(), dest.encoding());
|
masm.vhaddpd_rr(src.encoding(), dest.encoding());
|
||||||
}
|
}
|
||||||
void vsubpd(const Operand& src1, FloatRegister src0, FloatRegister dest) {
|
void vsubpd(FloatRegister src1, FloatRegister src0, FloatRegister dest) {
|
||||||
MOZ_ASSERT(HasSSE2());
|
MOZ_ASSERT(HasSSE2());
|
||||||
MOZ_ASSERT(src0.size() == 16);
|
MOZ_ASSERT(src0.size() == 16);
|
||||||
MOZ_ASSERT(dest.size() == 16);
|
MOZ_ASSERT(dest.size() == 16);
|
||||||
switch (src1.kind()) {
|
masm.vsubpd_rr(src1.encoding(), src0.encoding(), dest.encoding());
|
||||||
case Operand::MEM_REG_DISP:
|
|
||||||
masm.vsubpd_mr(src1.disp(), src1.base(), src0.encoding(), dest.encoding());
|
|
||||||
break;
|
|
||||||
case Operand::MEM_ADDRESS32:
|
|
||||||
masm.vsubpd_mr(src1.address(), src0.encoding(), dest.encoding());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("unexpected operand kind");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpunpckldq(FloatRegister src1, FloatRegister src0, FloatRegister dest) {
|
void vpunpckldq(FloatRegister src1, FloatRegister src0, FloatRegister dest) {
|
||||||
|
@ -130,14 +130,6 @@ class BaseAssemblerX86 : public BaseAssembler
|
|||||||
{
|
{
|
||||||
twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, src1, src0, dst);
|
twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, src1, src0, dst);
|
||||||
}
|
}
|
||||||
void vsubpd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst)
|
|
||||||
{
|
|
||||||
twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, offset, base, src0, dst);
|
|
||||||
}
|
|
||||||
void vsubpd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst)
|
|
||||||
{
|
|
||||||
twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, address, src0, dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vpunpckldq_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
|
void vpunpckldq_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) {
|
||||||
twoByteOpSimd("vpunpckldq", VEX_PD, OP2_PUNPCKLDQ, src1, src0, dst);
|
twoByteOpSimd("vpunpckldq", VEX_PD, OP2_PUNPCKLDQ, src1, src0, dst);
|
||||||
|
@ -21,21 +21,12 @@
|
|||||||
using namespace js;
|
using namespace js;
|
||||||
using namespace js::jit;
|
using namespace js::jit;
|
||||||
|
|
||||||
// vpunpckldq requires 16-byte boundary for memory operand.
|
|
||||||
// See convertUInt64ToDouble for the details.
|
|
||||||
MOZ_ALIGNED_DECL(static const uint64_t, 16) TO_DOUBLE[4] = {
|
|
||||||
0x4530000043300000LL,
|
|
||||||
0x0LL,
|
|
||||||
0x4330000000000000LL,
|
|
||||||
0x4530000000000000LL
|
|
||||||
};
|
|
||||||
|
|
||||||
static const double TO_DOUBLE_HIGH_SCALE = 0x100000000;
|
static const double TO_DOUBLE_HIGH_SCALE = 0x100000000;
|
||||||
|
|
||||||
void
|
void
|
||||||
MacroAssemblerX86::convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest)
|
MacroAssemblerX86::convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest)
|
||||||
{
|
{
|
||||||
#error check TenFourFox issue 526 and bug 1499198. may be safest to just always use the SSE2 routine
|
|
||||||
// SUBPD needs SSE2, HADDPD needs SSE3.
|
// SUBPD needs SSE2, HADDPD needs SSE3.
|
||||||
if (!HasSSE3()) {
|
if (!HasSSE3()) {
|
||||||
convertUInt32ToDouble(src.high, dest);
|
convertUInt32ToDouble(src.high, dest);
|
||||||
@ -71,8 +62,17 @@ MacroAssemblerX86::convertUInt64ToDouble(Register64 src, Register temp, FloatReg
|
|||||||
// here, each 64-bit part of dest represents following double:
|
// here, each 64-bit part of dest represents following double:
|
||||||
// HI(dest) = 0x 1.00000HHHHHHHH * 2**84 == 2**84 + 0x HHHHHHHH 00000000
|
// HI(dest) = 0x 1.00000HHHHHHHH * 2**84 == 2**84 + 0x HHHHHHHH 00000000
|
||||||
// LO(dest) = 0x 1.00000LLLLLLLL * 2**52 == 2**52 + 0x 00000000 LLLLLLLL
|
// LO(dest) = 0x 1.00000LLLLLLLL * 2**52 == 2**52 + 0x 00000000 LLLLLLLL
|
||||||
movePtr(ImmPtr(TO_DOUBLE), temp);
|
// See convertUInt64ToDouble for the details.
|
||||||
vpunpckldq(Operand(temp, 0), dest128, dest128);
|
static const int32_t CST1[4] = {
|
||||||
|
0x43300000,
|
||||||
|
0x45300000,
|
||||||
|
0x0,
|
||||||
|
0x0,
|
||||||
|
};
|
||||||
|
|
||||||
|
//loadConstantSimd128Int(SimdConstant::CreateX4(CST1), ScratchSimd128Reg);
|
||||||
|
loadConstantInt32x4(SimdConstant::CreateX4(CST1), ScratchSimd128Reg);
|
||||||
|
vpunpckldq(ScratchSimd128Reg, dest128, dest128);
|
||||||
|
|
||||||
// Subtract a constant C2 from dest, for each 64-bit part:
|
// Subtract a constant C2 from dest, for each 64-bit part:
|
||||||
// C2 = 0x 45300000 00000000 43300000 00000000
|
// C2 = 0x 45300000 00000000 43300000 00000000
|
||||||
@ -82,7 +82,16 @@ MacroAssemblerX86::convertUInt64ToDouble(Register64 src, Register temp, FloatReg
|
|||||||
// after the operation each 64-bit part of dest represents following:
|
// after the operation each 64-bit part of dest represents following:
|
||||||
// HI(dest) = double(0x HHHHHHHH 00000000)
|
// HI(dest) = double(0x HHHHHHHH 00000000)
|
||||||
// LO(dest) = double(0x 00000000 LLLLLLLL)
|
// LO(dest) = double(0x 00000000 LLLLLLLL)
|
||||||
vsubpd(Operand(temp, sizeof(uint64_t) * 2), dest128, dest128);
|
static const int32_t CST2[4] = {
|
||||||
|
0x0,
|
||||||
|
0x43300000,
|
||||||
|
0x0,
|
||||||
|
0x45300000,
|
||||||
|
};
|
||||||
|
|
||||||
|
//loadConstantSimd128Int(SimdConstant::CreateX4(CST2), ScratchSimd128Reg);
|
||||||
|
loadConstantInt32x4(SimdConstant::CreateX4(CST2), ScratchSimd128Reg);
|
||||||
|
vsubpd(ScratchSimd128Reg, dest128, dest128);
|
||||||
|
|
||||||
// Add HI(dest) and LO(dest) in double and store it into LO(dest),
|
// Add HI(dest) and LO(dest) in double and store it into LO(dest),
|
||||||
// LO(dest) = double(0x HHHHHHHH 00000000) + double(0x 00000000 LLLLLLLL)
|
// LO(dest) = double(0x HHHHHHHH 00000000) + double(0x 00000000 LLLLLLLL)
|
||||||
|
@ -2484,7 +2484,6 @@ nsNativeThemeCocoa::DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inB
|
|||||||
{
|
{
|
||||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||||
|
|
||||||
#if(0)
|
|
||||||
CGContextSaveGState(cgContext);
|
CGContextSaveGState(cgContext);
|
||||||
CGContextClipToRect(cgContext, inBoxRect);
|
CGContextClipToRect(cgContext, inBoxRect);
|
||||||
|
|
||||||
@ -2492,22 +2491,16 @@ nsNativeThemeCocoa::DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inB
|
|||||||
inBoxRect.size.height);
|
inBoxRect.size.height);
|
||||||
BOOL isMain = [aWindow isMainWindow];
|
BOOL isMain = [aWindow isMainWindow];
|
||||||
CGFloat titlebarHeight = unifiedHeight - inBoxRect.size.height;
|
CGFloat titlebarHeight = unifiedHeight - inBoxRect.size.height;
|
||||||
|
#if(0)
|
||||||
CGRect drawRect = CGRectMake(inBoxRect.origin.x, inBoxRect.origin.y - titlebarHeight,
|
CGRect drawRect = CGRectMake(inBoxRect.origin.x, inBoxRect.origin.y - titlebarHeight,
|
||||||
inBoxRect.size.width, inBoxRect.size.height + titlebarHeight);
|
inBoxRect.size.width, inBoxRect.size.height + titlebarHeight);
|
||||||
DrawNativeTitlebarToolbarWithSquareCorners(cgContext, drawRect, unifiedHeight, isMain, YES);
|
DrawNativeTitlebarToolbarWithSquareCorners(cgContext, drawRect, unifiedHeight, isMain, YES);
|
||||||
|
|
||||||
CGContextRestoreGState(cgContext);
|
|
||||||
#else
|
#else
|
||||||
// Backout bug 668195, 676241 et al.
|
// Backout bug 668195, 676241 et al.
|
||||||
// XXX This is probably not the best solution for the future because we
|
// XXX This is probably not the best solution for the future because we
|
||||||
// aren't actually upgrading the component calls, but it will suffice for now.
|
// aren't actually upgrading the component calls, but it will suffice for now.
|
||||||
|
|
||||||
float titlebarHeight = [(ToolbarWindow*)aWindow titlebarHeight];
|
|
||||||
// This may need modification (see above).
|
|
||||||
float unifiedHeight = titlebarHeight + inBoxRect.size.height;
|
|
||||||
|
|
||||||
BOOL isMain = [aWindow isMainWindow];
|
|
||||||
|
|
||||||
// Draw the gradient
|
// Draw the gradient
|
||||||
UnifiedGradientInfo info = { titlebarHeight, inBoxRect.size.height, isMain, NO };
|
UnifiedGradientInfo info = { titlebarHeight, inBoxRect.size.height, isMain, NO };
|
||||||
struct CGFunctionCallbacks callbacks = { 0, nsCocoaWindow::UnifiedShading, NULL };
|
struct CGFunctionCallbacks callbacks = { 0, nsCocoaWindow::UnifiedShading, NULL };
|
||||||
@ -2521,7 +2514,6 @@ nsNativeThemeCocoa::DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inB
|
|||||||
NO, NO);
|
NO, NO);
|
||||||
CGColorSpaceRelease(colorSpace);
|
CGColorSpaceRelease(colorSpace);
|
||||||
CGFunctionRelease(function);
|
CGFunctionRelease(function);
|
||||||
CGContextClipToRect(cgContext, inBoxRect);
|
|
||||||
CGContextDrawShading(cgContext, shading);
|
CGContextDrawShading(cgContext, shading);
|
||||||
CGShadingRelease(shading);
|
CGShadingRelease(shading);
|
||||||
|
|
||||||
@ -2531,6 +2523,7 @@ nsNativeThemeCocoa::DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inB
|
|||||||
inBoxRect.size.width, 1.0f);
|
inBoxRect.size.width, 1.0f);
|
||||||
DrawNativeGreyColorInRect(cgContext, headerBorderGrey, borderRect, isMain);
|
DrawNativeGreyColorInRect(cgContext, headerBorderGrey, borderRect, isMain);
|
||||||
#endif
|
#endif
|
||||||
|
CGContextRestoreGState(cgContext);
|
||||||
|
|
||||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||||
}
|
}
|
||||||
@ -2584,9 +2577,9 @@ nsNativeThemeCocoa::DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRec
|
|||||||
if (inBoxRect.size.height < 2.0f)
|
if (inBoxRect.size.height < 2.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
CGContextSaveGState(cgContext);
|
||||||
// backout bug 668195
|
// backout bug 668195
|
||||||
#if(0)
|
#if(0)
|
||||||
CGContextSaveGState(cgContext);
|
|
||||||
CGContextClipToRect(cgContext, inBoxRect);
|
CGContextClipToRect(cgContext, inBoxRect);
|
||||||
|
|
||||||
// kCUIWidgetWindowFrame draws a complete window frame with both title bar
|
// kCUIWidgetWindowFrame draws a complete window frame with both title bar
|
||||||
@ -2606,7 +2599,6 @@ nsNativeThemeCocoa::DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRec
|
|||||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||||
nil]);
|
nil]);
|
||||||
|
|
||||||
CGContextRestoreGState(cgContext);
|
|
||||||
#else
|
#else
|
||||||
BOOL isMain = [NativeWindowForFrame(aFrame) isMainWindow] || ![NSView focusView];
|
BOOL isMain = [NativeWindowForFrame(aFrame) isMainWindow] || ![NSView focusView];
|
||||||
|
|
||||||
@ -2623,6 +2615,7 @@ nsNativeThemeCocoa::DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRec
|
|||||||
NativeGreyColorAsFloat(statusbarGradientStartGrey, isMain),
|
NativeGreyColorAsFloat(statusbarGradientStartGrey, isMain),
|
||||||
NativeGreyColorAsFloat(statusbarGradientEndGrey, isMain));
|
NativeGreyColorAsFloat(statusbarGradientEndGrey, isMain));
|
||||||
#endif
|
#endif
|
||||||
|
CGContextRestoreGState(cgContext);
|
||||||
|
|
||||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user