blob: 6197388428a50d1027408de7c441355417954007 [file] [log] [blame]
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
*
* ***** BEGIN LICENSE BLOCK *****
* Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
#ifndef assembler_assembler_MacroAssembler_h
#define assembler_assembler_MacroAssembler_h
#include "assembler/wtf/Platform.h"
#if ENABLE_ASSEMBLER
#if WTF_CPU_ARM_THUMB2
#include "MacroAssemblerARMv7.h"
namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; }
#elif WTF_CPU_ARM_TRADITIONAL
#include "MacroAssemblerARM.h"
namespace JSC { typedef MacroAssemblerARM MacroAssemblerBase; }
#elif WTF_CPU_MIPS
#include "MacroAssemblerMIPS.h"
namespace JSC { typedef MacroAssemblerMIPS MacroAssemblerBase; }
#elif WTF_CPU_X86
#include "MacroAssemblerX86.h"
namespace JSC { typedef MacroAssemblerX86 MacroAssemblerBase; }
#elif WTF_CPU_X86_64
#include "MacroAssemblerX86_64.h"
namespace JSC { typedef MacroAssemblerX86_64 MacroAssemblerBase; }
#elif WTF_CPU_SPARC
#include "MacroAssemblerSparc.h"
namespace JSC { typedef MacroAssemblerSparc MacroAssemblerBase; }
#else
#error "The MacroAssembler is not supported on this platform."
#endif
namespace JSC {
class MacroAssembler : public MacroAssemblerBase {
public:
using MacroAssemblerBase::pop;
using MacroAssemblerBase::jump;
using MacroAssemblerBase::branch32;
using MacroAssemblerBase::branch16;
#if WTF_CPU_X86_64
using MacroAssemblerBase::branchPtr;
using MacroAssemblerBase::branchTestPtr;
#endif
// Platform agnostic onvenience functions,
// described in terms of other macro assembly methods.
void pop()
{
addPtr(Imm32(sizeof(void*)), stackPointerRegister);
}
void peek(RegisterID dest, int index = 0)
{
loadPtr(Address(stackPointerRegister, (index * sizeof(void*))), dest);
}
void poke(RegisterID src, int index = 0)
{
storePtr(src, Address(stackPointerRegister, (index * sizeof(void*))));
}
void poke(TrustedImm32 value, int index = 0)
{
store32(value, Address(stackPointerRegister, (index * sizeof(void*))));
}
void poke(TrustedImmPtr imm, int index = 0)
{
storePtr(imm, Address(stackPointerRegister, (index * sizeof(void*))));
}
// Backwards banches, these are currently all implemented using existing forwards branch mechanisms.
void branchPtr(Condition cond, RegisterID op1, ImmPtr imm, Label target)
{
branchPtr(cond, op1, imm).linkTo(target, this);
}
void branch32(Condition cond, RegisterID op1, RegisterID op2, Label target)
{
branch32(cond, op1, op2).linkTo(target, this);
}
void branch32(Condition cond, RegisterID op1, TrustedImm32 imm, Label target)
{
branch32(cond, op1, imm).linkTo(target, this);
}
void branch32(Condition cond, RegisterID left, Address right, Label target)
{
branch32(cond, left, right).linkTo(target, this);
}
void branch16(Condition cond, BaseIndex left, RegisterID right, Label target)
{
branch16(cond, left, right).linkTo(target, this);
}
void branchTestPtr(Condition cond, RegisterID reg, Label target)
{
branchTestPtr(cond, reg).linkTo(target, this);
}
void jump(Label target)
{
jump().linkTo(target, this);
}
// Ptr methods
// On 32-bit platforms (i.e. x86), these methods directly map onto their 32-bit equivalents.
// FIXME: should this use a test for 32-bitness instead of this specific exception?
#if !WTF_CPU_X86_64
void addPtr(RegisterID src, RegisterID dest)
{
add32(src, dest);
}
void addPtr(Imm32 imm32, Address address)
{
add32(imm32, address);
}
void addPtr(Imm32 imm, RegisterID srcDest)
{
add32(imm, srcDest);
}
void addPtr(ImmPtr imm, RegisterID dest)
{
add32(Imm32(imm), dest);
}
void addPtr(Imm32 imm, RegisterID src, RegisterID dest)
{
add32(imm, src, dest);
}
void andPtr(RegisterID src, RegisterID dest)
{
and32(src, dest);
}
void andPtr(Imm32 imm, RegisterID srcDest)
{
and32(imm, srcDest);
}
void andPtr(ImmPtr ptr, RegisterID srcDest)
{
and32(Imm32(ptr), srcDest);
}
void negPtr(RegisterID srcDest)
{
neg32(srcDest);
}
void notPtr(RegisterID srcDest)
{
not32(srcDest);
}
void orPtr(RegisterID src, RegisterID dest)
{
or32(src, dest);
}
void orPtr(ImmPtr imm, RegisterID dest)
{
or32(Imm32(imm), dest);
}
void orPtr(Imm32 imm, RegisterID dest)
{
or32(imm, dest);
}
void subPtr(RegisterID src, RegisterID dest)
{
sub32(src, dest);
}
void subPtr(Imm32 imm, RegisterID dest)
{
sub32(imm, dest);
}
void subPtr(ImmPtr imm, RegisterID dest)
{
sub32(Imm32(imm), dest);
}
void subPtr(ImmPtr imm, Address address)
{
sub32(Imm32(imm), address);
}
void xorPtr(RegisterID src, RegisterID dest)
{
xor32(src, dest);
}
void xorPtr(Imm32 imm, RegisterID srcDest)
{
xor32(imm, srcDest);
}
void loadPtr(ImplicitAddress address, RegisterID dest)
{
load32(address, dest);
}
void loadPtr(BaseIndex address, RegisterID dest)
{
load32(address, dest);
}
void loadPtr(void* address, RegisterID dest)
{
load32(address, dest);
}
DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
{
return load32WithAddressOffsetPatch(address, dest);
}
void setPtr(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
{
set32(cond, left, right, dest);
}
void storePtr(RegisterID src, ImplicitAddress address)
{
store32(src, address);
}
void storePtr(RegisterID src, void* address)
{
store32(src, address);
}
void storePtr(TrustedImmPtr imm, ImplicitAddress address)
{
store32(Imm32(imm), address);
}
void storePtr(TrustedImmPtr imm, BaseIndex address)
{
store32(Imm32(imm), address);
}
void storePtr(TrustedImmPtr imm, void* address)
{
store32(Imm32(imm), address);
}
DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
{
return store32WithAddressOffsetPatch(src, address);
}
Jump branchPtr(Condition cond, RegisterID left, RegisterID right)
{
return branch32(cond, left, right);
}
Jump branchPtr(Condition cond, RegisterID left, ImmPtr right)
{
return branch32(cond, left, Imm32(right));
}
Jump branchPtr(Condition cond, RegisterID left, Imm32 right)
{
return branch32(cond, left, right);
}
Jump branchPtr(Condition cond, RegisterID left, Address right)
{
return branch32(cond, left, right);
}
Jump branchPtr(Condition cond, Address left, RegisterID right)
{
return branch32(cond, left, right);
}
Jump branchPtr(Condition cond, AbsoluteAddress left, RegisterID right)
{
return branch32(cond, left, right);
}
Jump branchPtr(Condition cond, Address left, ImmPtr right)
{
return branch32(cond, left, Imm32(right));
}
Jump branchPtr(Condition cond, AbsoluteAddress left, ImmPtr right, RegisterID scratch)
{
return branch32(cond, left, Imm32(right));
}
Jump branchTestPtr(Condition cond, RegisterID reg, RegisterID mask)
{
return branchTest32(cond, reg, mask);
}
Jump branchTestPtr(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
{
return branchTest32(cond, reg, mask);
}
Jump branchTestPtr(Condition cond, Address address, Imm32 mask = Imm32(-1))
{
return branchTest32(cond, address, mask);
}
Jump branchTestPtr(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
{
return branchTest32(cond, address, mask);
}
Jump branchAddPtr(Condition cond, RegisterID src, RegisterID dest)
{
return branchAdd32(cond, src, dest);
}
Jump branchSubPtr(Condition cond, Imm32 imm, RegisterID dest)
{
return branchSub32(cond, imm, dest);
}
using MacroAssemblerBase::branchTest8;
Jump branchTest8(Condition cond, ExtendedAddress address, Imm32 mask = Imm32(-1))
{
return MacroAssemblerBase::branchTest8(cond, Address(address.base, address.offset), mask);
}
void rshiftPtr(Imm32 imm, RegisterID dest)
{
rshift32(imm, dest);
}
void lshiftPtr(Imm32 imm, RegisterID dest)
{
lshift32(imm, dest);
}
#endif
};
} // namespace JSC
#endif // ENABLE(ASSEMBLER)
#endif /* assembler_assembler_MacroAssembler_h */