]>
git.saurik.com Git - apple/javascriptcore.git/blob - assembler/MacroAssemblerARM.cpp
2 * Copyright (C) 2013 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 <wtf/StdLibExtras.h>
39 #include <sys/types.h>
44 #include <asm/hwcap.h>
49 static bool isVFPPresent()
52 int fd
= open("/proc/self/auxv", O_RDONLY
);
55 while (read(fd
, &aux
, sizeof(Elf32_auxv_t
))) {
56 if (aux
.a_type
== AT_HWCAP
) {
58 return aux
.a_un
.a_val
& HWCAP_VFP
;
65 #if (COMPILER(GCC) && defined(__VFP_FP__))
72 const bool MacroAssemblerARM::s_isVFPPresent
= isVFPPresent();
74 #if CPU(ARMV5_OR_LOWER)
75 /* On ARMv5 and below, natural alignment is required. */
76 void MacroAssemblerARM::load32WithUnalignedHalfWords(BaseIndex address
, RegisterID dest
)
80 ASSERT(address
.scale
>= 0 && address
.scale
<= 3);
81 op2
= m_assembler
.lsl(address
.index
, static_cast<int>(address
.scale
));
83 if (address
.offset
>= 0 && address
.offset
+ 0x2 <= 0xff) {
84 m_assembler
.add(ARMRegisters::S0
, address
.base
, op2
);
85 m_assembler
.halfDtrUp(ARMAssembler::LoadUint16
, dest
, ARMRegisters::S0
, ARMAssembler::getOp2Half(address
.offset
));
86 m_assembler
.halfDtrUp(ARMAssembler::LoadUint16
, ARMRegisters::S0
, ARMRegisters::S0
, ARMAssembler::getOp2Half(address
.offset
+ 0x2));
87 } else if (address
.offset
< 0 && address
.offset
>= -0xff) {
88 m_assembler
.add(ARMRegisters::S0
, address
.base
, op2
);
89 m_assembler
.halfDtrDown(ARMAssembler::LoadUint16
, dest
, ARMRegisters::S0
, ARMAssembler::getOp2Half(-address
.offset
));
90 m_assembler
.halfDtrDown(ARMAssembler::LoadUint16
, ARMRegisters::S0
, ARMRegisters::S0
, ARMAssembler::getOp2Half(-address
.offset
- 0x2));
92 m_assembler
.moveImm(address
.offset
, ARMRegisters::S0
);
93 m_assembler
.add(ARMRegisters::S0
, ARMRegisters::S0
, op2
);
94 m_assembler
.halfDtrUpRegister(ARMAssembler::LoadUint16
, dest
, address
.base
, ARMRegisters::S0
);
95 m_assembler
.add(ARMRegisters::S0
, ARMRegisters::S0
, ARMAssembler::Op2Immediate
| 0x2);
96 m_assembler
.halfDtrUpRegister(ARMAssembler::LoadUint16
, ARMRegisters::S0
, address
.base
, ARMRegisters::S0
);
98 m_assembler
.orr(dest
, dest
, m_assembler
.lsl(ARMRegisters::S0
, 16));
100 #endif // CPU(ARMV5_OR_LOWER)
104 void MacroAssemblerARM::ProbeContext::dumpCPURegisters(const char* indentation
)
106 #define DUMP_GPREGISTER(_type, _regName) { \
107 int32_t value = reinterpret_cast<int32_t>(cpu._regName); \
108 dataLogF("%s %5s: 0x%08x %d\n", indentation, #_regName, value, value) ; \
110 FOR_EACH_CPU_GPREGISTER(DUMP_GPREGISTER
)
111 FOR_EACH_CPU_SPECIAL_REGISTER(DUMP_GPREGISTER
)
112 #undef DUMP_GPREGISTER
114 #define DUMP_FPREGISTER(_type, _regName) { \
115 uint32_t* u = reinterpret_cast<uint32_t*>(&cpu._regName); \
116 double* d = reinterpret_cast<double*>(&cpu._regName); \
117 dataLogF("%s %5s: 0x %08x %08x %12g\n", \
118 indentation, #_regName, u[1], u[0], d[0]); \
120 FOR_EACH_CPU_FPREGISTER(DUMP_FPREGISTER
)
121 #undef DUMP_FPREGISTER
124 void MacroAssemblerARM::ProbeContext::dump(const char* indentation
)
129 dataLogF("%sProbeContext %p {\n", indentation
, this);
130 dataLogF("%s probeFunction: %p\n", indentation
, probeFunction
);
131 dataLogF("%s arg1: %p %llu\n", indentation
, arg1
, reinterpret_cast<int64_t>(arg1
));
132 dataLogF("%s arg2: %p %llu\n", indentation
, arg2
, reinterpret_cast<int64_t>(arg2
));
133 dataLogF("%s cpu: {\n", indentation
);
135 dumpCPURegisters(indentation
);
137 dataLogF("%s }\n", indentation
);
138 dataLogF("%s}\n", indentation
);
142 extern "C" void ctiMasmProbeTrampoline();
144 // For details on "What code is emitted for the probe?" and "What values are in
145 // the saved registers?", see comment for MacroAssemblerX86::probe() in
146 // MacroAssemblerX86_64.h.
148 void MacroAssemblerARM::probe(MacroAssemblerARM::ProbeFunction function
, void* arg1
, void* arg2
)
150 push(RegisterID::sp
);
151 push(RegisterID::lr
);
152 push(RegisterID::ip
);
153 push(RegisterID::S0
);
154 // The following uses RegisterID::S0. So, they must come after we push S0 above.
155 push(trustedImm32FromPtr(arg2
));
156 push(trustedImm32FromPtr(arg1
));
157 push(trustedImm32FromPtr(function
));
159 move(trustedImm32FromPtr(ctiMasmProbeTrampoline
), RegisterID::S0
);
160 m_assembler
.blx(RegisterID::S0
);
163 #endif // USE(MASM_PROBE)
167 #endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)