]>
git.saurik.com Git - apple/javascriptcore.git/blob - assembler/MacroAssemblerARM.cpp
2500d84871340987eaca99ff39c79dd5ff5e42d4
2 * Copyright (C) 2013, 2014 Apple Inc.
3 * Copyright (C) 2009 University of Szeged
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
32 #include "MacroAssemblerARM.h"
35 #include <sys/types.h>
40 #include <asm/hwcap.h>
45 static bool isVFPPresent()
48 int fd
= open("/proc/self/auxv", O_RDONLY
);
51 while (read(fd
, &aux
, sizeof(Elf32_auxv_t
))) {
52 if (aux
.a_type
== AT_HWCAP
) {
54 return aux
.a_un
.a_val
& HWCAP_VFP
;
61 #if (COMPILER(GCC) && defined(__VFP_FP__))
68 const bool MacroAssemblerARM::s_isVFPPresent
= isVFPPresent();
70 #if CPU(ARMV5_OR_LOWER)
71 /* On ARMv5 and below, natural alignment is required. */
72 void MacroAssemblerARM::load32WithUnalignedHalfWords(BaseIndex address
, RegisterID dest
)
76 ASSERT(address
.scale
>= 0 && address
.scale
<= 3);
77 op2
= m_assembler
.lsl(address
.index
, static_cast<int>(address
.scale
));
79 if (address
.offset
>= 0 && address
.offset
+ 0x2 <= 0xff) {
80 m_assembler
.add(ARMRegisters::S0
, address
.base
, op2
);
81 m_assembler
.halfDtrUp(ARMAssembler::LoadUint16
, dest
, ARMRegisters::S0
, ARMAssembler::getOp2Half(address
.offset
));
82 m_assembler
.halfDtrUp(ARMAssembler::LoadUint16
, ARMRegisters::S0
, ARMRegisters::S0
, ARMAssembler::getOp2Half(address
.offset
+ 0x2));
83 } else if (address
.offset
< 0 && address
.offset
>= -0xff) {
84 m_assembler
.add(ARMRegisters::S0
, address
.base
, op2
);
85 m_assembler
.halfDtrDown(ARMAssembler::LoadUint16
, dest
, ARMRegisters::S0
, ARMAssembler::getOp2Half(-address
.offset
));
86 m_assembler
.halfDtrDown(ARMAssembler::LoadUint16
, ARMRegisters::S0
, ARMRegisters::S0
, ARMAssembler::getOp2Half(-address
.offset
- 0x2));
88 m_assembler
.moveImm(address
.offset
, ARMRegisters::S0
);
89 m_assembler
.add(ARMRegisters::S0
, ARMRegisters::S0
, op2
);
90 m_assembler
.halfDtrUpRegister(ARMAssembler::LoadUint16
, dest
, address
.base
, ARMRegisters::S0
);
91 m_assembler
.add(ARMRegisters::S0
, ARMRegisters::S0
, ARMAssembler::Op2Immediate
| 0x2);
92 m_assembler
.halfDtrUpRegister(ARMAssembler::LoadUint16
, ARMRegisters::S0
, address
.base
, ARMRegisters::S0
);
94 m_assembler
.orr(dest
, dest
, m_assembler
.lsl(ARMRegisters::S0
, 16));
96 #endif // CPU(ARMV5_OR_LOWER)
98 #if ENABLE(MASM_PROBE)
100 #define INDENT printIndent(indentation)
102 void MacroAssemblerARM::printCPURegisters(CPUState
& cpu
, int indentation
)
104 #define PRINT_GPREGISTER(_type, _regName) { \
105 int32_t value = reinterpret_cast<int32_t>(cpu._regName); \
106 INDENT, dataLogF("%5s: 0x%08x %d\n", #_regName, value, value) ; \
108 FOR_EACH_CPU_GPREGISTER(PRINT_GPREGISTER
)
109 FOR_EACH_CPU_SPECIAL_REGISTER(PRINT_GPREGISTER
)
110 #undef PRINT_GPREGISTER
112 #define PRINT_FPREGISTER(_type, _regName) { \
113 uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \
114 double* d = reinterpret_cast<double*>(&cpu._regName); \
115 INDENT, dataLogF("%5s: 0x%016llx %.13g\n", #_regName, *u, *d); \
117 FOR_EACH_CPU_FPREGISTER(PRINT_FPREGISTER
)
118 #undef PRINT_FPREGISTER
123 void MacroAssemblerARM::printRegister(MacroAssemblerARM::CPUState
& cpu
, RegisterID regID
)
125 const char* name
= CPUState::registerName(regID
);
128 intptr_t intptrValue
;
130 u
.voidPtr
= cpu
.registerValue(regID
);
131 dataLogF("%s:<%p %ld>", name
, u
.voidPtr
, u
.intptrValue
);
134 void MacroAssemblerARM::printRegister(MacroAssemblerARM::CPUState
& cpu
, FPRegisterID regID
)
136 const char* name
= CPUState::registerName(regID
);
139 uint64_t uint64Value
;
141 u
.doubleValue
= cpu
.registerValue(regID
);
142 dataLogF("%s:<0x%016llx %.13g>", name
, u
.uint64Value
, u
.doubleValue
);
145 extern "C" void ctiMasmProbeTrampoline();
147 // For details on "What code is emitted for the probe?" and "What values are in
148 // the saved registers?", see comment for MacroAssemblerX86Common::probe() in
149 // MacroAssemblerX86Common.cpp.
151 void MacroAssemblerARM::probe(MacroAssemblerARM::ProbeFunction function
, void* arg1
, void* arg2
)
153 push(RegisterID::sp
);
154 push(RegisterID::lr
);
155 push(RegisterID::ip
);
156 push(RegisterID::S0
);
157 // The following uses RegisterID::S0. So, they must come after we push S0 above.
158 push(trustedImm32FromPtr(arg2
));
159 push(trustedImm32FromPtr(arg1
));
160 push(trustedImm32FromPtr(function
));
162 move(trustedImm32FromPtr(ctiMasmProbeTrampoline
), RegisterID::S0
);
163 m_assembler
.blx(RegisterID::S0
);
166 #endif // ENABLE(MASM_PROBE)
170 #endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)