xref: /aosp_15_r20/art/compiler/utils/assembler_thumb_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include <dirent.h>
18*795d594fSAndroid Build Coastguard Worker #include <errno.h>
19*795d594fSAndroid Build Coastguard Worker #include <string.h>
20*795d594fSAndroid Build Coastguard Worker #include <sys/types.h>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include <fstream>
23*795d594fSAndroid Build Coastguard Worker #include <map>
24*795d594fSAndroid Build Coastguard Worker #include <regex>
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker #include "jni/quick/calling_convention.h"
29*795d594fSAndroid Build Coastguard Worker #include "utils/arm/jni_macro_assembler_arm_vixl.h"
30*795d594fSAndroid Build Coastguard Worker #include "utils/assembler_test_base.h"
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker #include "base/hex_dump.h"
33*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
34*795d594fSAndroid Build Coastguard Worker #include "base/malloc_arena_pool.h"
35*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h"
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
38*795d594fSAndroid Build Coastguard Worker namespace arm {
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker // Include results file (generated manually)
41*795d594fSAndroid Build Coastguard Worker #include "assembler_thumb_test_expected.cc.inc"
42*795d594fSAndroid Build Coastguard Worker 
43*795d594fSAndroid Build Coastguard Worker class ArmVIXLAssemblerTest : public AssemblerTestBase {
44*795d594fSAndroid Build Coastguard Worker  public:
ArmVIXLAssemblerTest()45*795d594fSAndroid Build Coastguard Worker   ArmVIXLAssemblerTest() : pool(), allocator(&pool), assembler(&allocator) { }
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker  protected:
GetIsa()48*795d594fSAndroid Build Coastguard Worker   InstructionSet GetIsa() override { return InstructionSet::kThumb2; }
49*795d594fSAndroid Build Coastguard Worker 
DumpAndCheck(std::vector<uint8_t> & code,const char * testname,const std::string & expected)50*795d594fSAndroid Build Coastguard Worker   void DumpAndCheck(std::vector<uint8_t>& code, const char* testname, const std::string& expected) {
51*795d594fSAndroid Build Coastguard Worker #ifndef ART_TARGET_ANDROID
52*795d594fSAndroid Build Coastguard Worker     std::string obj_file = scratch_dir_->GetPath() + testname + ".o";
53*795d594fSAndroid Build Coastguard Worker     WriteElf</*IsElf64=*/false>(obj_file, InstructionSet::kThumb2, code);
54*795d594fSAndroid Build Coastguard Worker     std::string disassembly;
55*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(Disassemble(obj_file, &disassembly));
56*795d594fSAndroid Build Coastguard Worker 
57*795d594fSAndroid Build Coastguard Worker     // objdump on buildbot seems to sometimes add annotation like in "bne #226 <.text+0x1e8>".
58*795d594fSAndroid Build Coastguard Worker     // It is unclear why it does not reproduce locally. As work-around, remove the annotation.
59*795d594fSAndroid Build Coastguard Worker     std::regex annotation_re(" <\\.text\\+\\w+>");
60*795d594fSAndroid Build Coastguard Worker     disassembly = std::regex_replace(disassembly, annotation_re, "");
61*795d594fSAndroid Build Coastguard Worker 
62*795d594fSAndroid Build Coastguard Worker     std::string expected2 = "\n" +
63*795d594fSAndroid Build Coastguard Worker         obj_file + ": file format elf32-littlearm\n\n"
64*795d594fSAndroid Build Coastguard Worker         "Disassembly of section .text:\n\n"
65*795d594fSAndroid Build Coastguard Worker         "00000000 <.text>:\n" +
66*795d594fSAndroid Build Coastguard Worker         expected;
67*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(expected2, disassembly);
68*795d594fSAndroid Build Coastguard Worker     if (expected2 != disassembly) {
69*795d594fSAndroid Build Coastguard Worker       std::string out = "  \"" + Replace(disassembly, "\n", "\\n\"\n  \"") + "\"";
70*795d594fSAndroid Build Coastguard Worker       printf("C++ formatted disassembler output for %s:\n%s\n", testname, out.c_str());
71*795d594fSAndroid Build Coastguard Worker     }
72*795d594fSAndroid Build Coastguard Worker #endif  // ART_TARGET_ANDROID
73*795d594fSAndroid Build Coastguard Worker   }
74*795d594fSAndroid Build Coastguard Worker 
75*795d594fSAndroid Build Coastguard Worker #define __ assembler.
76*795d594fSAndroid Build Coastguard Worker 
EmitAndCheck(const char * testname,const char * expected)77*795d594fSAndroid Build Coastguard Worker   void EmitAndCheck(const char* testname, const char* expected) {
78*795d594fSAndroid Build Coastguard Worker     __ FinalizeCode();
79*795d594fSAndroid Build Coastguard Worker     size_t cs = __ CodeSize();
80*795d594fSAndroid Build Coastguard Worker     std::vector<uint8_t> managed_code(cs);
81*795d594fSAndroid Build Coastguard Worker     MemoryRegion code(&managed_code[0], managed_code.size());
82*795d594fSAndroid Build Coastguard Worker     __ CopyInstructions(code);
83*795d594fSAndroid Build Coastguard Worker 
84*795d594fSAndroid Build Coastguard Worker     DumpAndCheck(managed_code, testname, expected);
85*795d594fSAndroid Build Coastguard Worker   }
86*795d594fSAndroid Build Coastguard Worker 
87*795d594fSAndroid Build Coastguard Worker #undef __
88*795d594fSAndroid Build Coastguard Worker 
89*795d594fSAndroid Build Coastguard Worker #define __ assembler.
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker   MallocArenaPool pool;
92*795d594fSAndroid Build Coastguard Worker   ArenaAllocator allocator;
93*795d594fSAndroid Build Coastguard Worker   ArmVIXLJNIMacroAssembler assembler;
94*795d594fSAndroid Build Coastguard Worker };
95*795d594fSAndroid Build Coastguard Worker 
TEST_F(ArmVIXLAssemblerTest,VixlJniHelpers)96*795d594fSAndroid Build Coastguard Worker TEST_F(ArmVIXLAssemblerTest, VixlJniHelpers) {
97*795d594fSAndroid Build Coastguard Worker   // Run the test only with Baker read barriers, as the expected
98*795d594fSAndroid Build Coastguard Worker   // generated code contains a Marking Register refresh instruction.
99*795d594fSAndroid Build Coastguard Worker   TEST_DISABLED_WITHOUT_BAKER_READ_BARRIERS();
100*795d594fSAndroid Build Coastguard Worker 
101*795d594fSAndroid Build Coastguard Worker   const bool is_static = true;
102*795d594fSAndroid Build Coastguard Worker   const bool is_synchronized = false;
103*795d594fSAndroid Build Coastguard Worker   const bool is_fast_native = false;
104*795d594fSAndroid Build Coastguard Worker   const bool is_critical_native = false;
105*795d594fSAndroid Build Coastguard Worker   const char* shorty = "IIFII";
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<JniCallingConvention> jni_conv(
108*795d594fSAndroid Build Coastguard Worker       JniCallingConvention::Create(&allocator,
109*795d594fSAndroid Build Coastguard Worker                                    is_static,
110*795d594fSAndroid Build Coastguard Worker                                    is_synchronized,
111*795d594fSAndroid Build Coastguard Worker                                    is_fast_native,
112*795d594fSAndroid Build Coastguard Worker                                    is_critical_native,
113*795d594fSAndroid Build Coastguard Worker                                    shorty,
114*795d594fSAndroid Build Coastguard Worker                                    InstructionSet::kThumb2));
115*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<ManagedRuntimeCallingConvention> mr_conv(
116*795d594fSAndroid Build Coastguard Worker       ManagedRuntimeCallingConvention::Create(
117*795d594fSAndroid Build Coastguard Worker           &allocator, is_static, is_synchronized, shorty, InstructionSet::kThumb2));
118*795d594fSAndroid Build Coastguard Worker   const int frame_size(jni_conv->FrameSize());
119*795d594fSAndroid Build Coastguard Worker   ArrayRef<const ManagedRegister> callee_save_regs = jni_conv->CalleeSaveRegisters();
120*795d594fSAndroid Build Coastguard Worker 
121*795d594fSAndroid Build Coastguard Worker   const ManagedRegister method_register = ArmManagedRegister::FromCoreRegister(R0);
122*795d594fSAndroid Build Coastguard Worker   const ManagedRegister hidden_arg_register = ArmManagedRegister::FromCoreRegister(R4);
123*795d594fSAndroid Build Coastguard Worker   const ManagedRegister scratch_register = ArmManagedRegister::FromCoreRegister(R12);
124*795d594fSAndroid Build Coastguard Worker 
125*795d594fSAndroid Build Coastguard Worker   __ BuildFrame(frame_size, mr_conv->MethodRegister(), callee_save_regs);
126*795d594fSAndroid Build Coastguard Worker 
127*795d594fSAndroid Build Coastguard Worker   // Spill arguments.
128*795d594fSAndroid Build Coastguard Worker   mr_conv->ResetIterator(FrameOffset(frame_size));
129*795d594fSAndroid Build Coastguard Worker   for (; mr_conv->HasNext(); mr_conv->Next()) {
130*795d594fSAndroid Build Coastguard Worker     if (mr_conv->IsCurrentParamInRegister()) {
131*795d594fSAndroid Build Coastguard Worker       size_t size = mr_conv->IsCurrentParamALongOrDouble() ? 8u : 4u;
132*795d594fSAndroid Build Coastguard Worker       __ Store(mr_conv->CurrentParamStackOffset(), mr_conv->CurrentParamRegister(), size);
133*795d594fSAndroid Build Coastguard Worker     }
134*795d594fSAndroid Build Coastguard Worker   }
135*795d594fSAndroid Build Coastguard Worker   __ IncreaseFrameSize(32);
136*795d594fSAndroid Build Coastguard Worker 
137*795d594fSAndroid Build Coastguard Worker   // Loads
138*795d594fSAndroid Build Coastguard Worker   __ IncreaseFrameSize(4096);
139*795d594fSAndroid Build Coastguard Worker   __ Load(method_register, FrameOffset(32), 4);
140*795d594fSAndroid Build Coastguard Worker   __ Load(method_register, FrameOffset(124), 4);
141*795d594fSAndroid Build Coastguard Worker   __ Load(method_register, FrameOffset(132), 4);
142*795d594fSAndroid Build Coastguard Worker   __ Load(method_register, FrameOffset(1020), 4);
143*795d594fSAndroid Build Coastguard Worker   __ Load(method_register, FrameOffset(1024), 4);
144*795d594fSAndroid Build Coastguard Worker   __ Load(scratch_register, FrameOffset(4092), 4);
145*795d594fSAndroid Build Coastguard Worker   __ Load(scratch_register, FrameOffset(4096), 4);
146*795d594fSAndroid Build Coastguard Worker   __ LoadRawPtrFromThread(scratch_register, ThreadOffset32(512));
147*795d594fSAndroid Build Coastguard Worker 
148*795d594fSAndroid Build Coastguard Worker   // Stores
149*795d594fSAndroid Build Coastguard Worker   __ Store(FrameOffset(32), method_register, 4);
150*795d594fSAndroid Build Coastguard Worker   __ Store(FrameOffset(124), method_register, 4);
151*795d594fSAndroid Build Coastguard Worker   __ Store(FrameOffset(132), method_register, 4);
152*795d594fSAndroid Build Coastguard Worker   __ Store(FrameOffset(1020), method_register, 4);
153*795d594fSAndroid Build Coastguard Worker   __ Store(FrameOffset(1024), method_register, 4);
154*795d594fSAndroid Build Coastguard Worker   __ Store(FrameOffset(4092), scratch_register, 4);
155*795d594fSAndroid Build Coastguard Worker   __ Store(FrameOffset(4096), scratch_register, 4);
156*795d594fSAndroid Build Coastguard Worker   __ StoreRawPtr(FrameOffset(48), scratch_register);
157*795d594fSAndroid Build Coastguard Worker   __ StoreStackPointerToThread(ThreadOffset32(512), false);
158*795d594fSAndroid Build Coastguard Worker   __ StoreStackPointerToThread(ThreadOffset32(512), true);
159*795d594fSAndroid Build Coastguard Worker 
160*795d594fSAndroid Build Coastguard Worker   // MoveArguments
161*795d594fSAndroid Build Coastguard Worker   static constexpr FrameOffset kInvalidReferenceOffset =
162*795d594fSAndroid Build Coastguard Worker       JNIMacroAssembler<kArmPointerSize>::kInvalidReferenceOffset;
163*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kNativePointerSize = static_cast<size_t>(kArmPointerSize);
164*795d594fSAndroid Build Coastguard Worker   // Normal or @FastNative with parameters (Object, long, long, int, Object).
165*795d594fSAndroid Build Coastguard Worker   // Note: This shall not spill the reference R1 to [sp, #36]. The JNI compiler spills
166*795d594fSAndroid Build Coastguard Worker   // references in an separate initial pass before moving arguments and creating `jobject`s.
167*795d594fSAndroid Build Coastguard Worker   ArgumentLocation move_dests1[] = {
168*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(ArmManagedRegister::FromCoreRegister(R2), kNativePointerSize),
169*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(0), 2 * kVRegSize),
170*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(8), 2 * kVRegSize),
171*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(16), kVRegSize),
172*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(20), kNativePointerSize),
173*795d594fSAndroid Build Coastguard Worker   };
174*795d594fSAndroid Build Coastguard Worker   ArgumentLocation move_srcs1[] = {
175*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(ArmManagedRegister::FromCoreRegister(R1), kVRegSize),
176*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(ArmManagedRegister::FromRegisterPair(R2_R3), 2 * kVRegSize),
177*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(48), 2 * kVRegSize),
178*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(56), kVRegSize),
179*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(60), kVRegSize),
180*795d594fSAndroid Build Coastguard Worker   };
181*795d594fSAndroid Build Coastguard Worker   FrameOffset move_refs1[] {
182*795d594fSAndroid Build Coastguard Worker       FrameOffset(36),
183*795d594fSAndroid Build Coastguard Worker       FrameOffset(kInvalidReferenceOffset),
184*795d594fSAndroid Build Coastguard Worker       FrameOffset(kInvalidReferenceOffset),
185*795d594fSAndroid Build Coastguard Worker       FrameOffset(kInvalidReferenceOffset),
186*795d594fSAndroid Build Coastguard Worker       FrameOffset(60),
187*795d594fSAndroid Build Coastguard Worker   };
188*795d594fSAndroid Build Coastguard Worker   __ MoveArguments(ArrayRef<ArgumentLocation>(move_dests1),
189*795d594fSAndroid Build Coastguard Worker                    ArrayRef<ArgumentLocation>(move_srcs1),
190*795d594fSAndroid Build Coastguard Worker                    ArrayRef<FrameOffset>(move_refs1));
191*795d594fSAndroid Build Coastguard Worker   // @CriticalNative with parameters (long, long, long, int).
192*795d594fSAndroid Build Coastguard Worker   ArgumentLocation move_dests2[] = {
193*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(ArmManagedRegister::FromRegisterPair(R0_R1), 2 * kVRegSize),
194*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(ArmManagedRegister::FromRegisterPair(R2_R3), 2 * kVRegSize),
195*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(0), 2 * kVRegSize),
196*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(8), kVRegSize),
197*795d594fSAndroid Build Coastguard Worker   };
198*795d594fSAndroid Build Coastguard Worker   ArgumentLocation move_srcs2[] = {
199*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(ArmManagedRegister::FromRegisterPair(R2_R3), 2 * kVRegSize),
200*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(28), kVRegSize),
201*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(32), 2 * kVRegSize),
202*795d594fSAndroid Build Coastguard Worker       ArgumentLocation(FrameOffset(40), kVRegSize),
203*795d594fSAndroid Build Coastguard Worker   };
204*795d594fSAndroid Build Coastguard Worker   FrameOffset move_refs2[] {
205*795d594fSAndroid Build Coastguard Worker       FrameOffset(kInvalidReferenceOffset),
206*795d594fSAndroid Build Coastguard Worker       FrameOffset(kInvalidReferenceOffset),
207*795d594fSAndroid Build Coastguard Worker       FrameOffset(kInvalidReferenceOffset),
208*795d594fSAndroid Build Coastguard Worker       FrameOffset(kInvalidReferenceOffset),
209*795d594fSAndroid Build Coastguard Worker   };
210*795d594fSAndroid Build Coastguard Worker   __ MoveArguments(ArrayRef<ArgumentLocation>(move_dests2),
211*795d594fSAndroid Build Coastguard Worker                    ArrayRef<ArgumentLocation>(move_srcs2),
212*795d594fSAndroid Build Coastguard Worker                    ArrayRef<FrameOffset>(move_refs2));
213*795d594fSAndroid Build Coastguard Worker 
214*795d594fSAndroid Build Coastguard Worker   // Other
215*795d594fSAndroid Build Coastguard Worker   __ Call(method_register, FrameOffset(48));
216*795d594fSAndroid Build Coastguard Worker   __ Copy(FrameOffset(48), FrameOffset(44), 4);
217*795d594fSAndroid Build Coastguard Worker   __ GetCurrentThread(method_register);
218*795d594fSAndroid Build Coastguard Worker   __ GetCurrentThread(FrameOffset(48));
219*795d594fSAndroid Build Coastguard Worker   __ Move(hidden_arg_register, method_register, 4);
220*795d594fSAndroid Build Coastguard Worker   __ VerifyObject(scratch_register, false);
221*795d594fSAndroid Build Coastguard Worker 
222*795d594fSAndroid Build Coastguard Worker   // Note: `CreateJObject()` may need the scratch register IP. Test with another high register.
223*795d594fSAndroid Build Coastguard Worker   const ManagedRegister high_register = ArmManagedRegister::FromCoreRegister(R11);
224*795d594fSAndroid Build Coastguard Worker   __ CreateJObject(high_register, FrameOffset(48), high_register, true);
225*795d594fSAndroid Build Coastguard Worker   __ CreateJObject(high_register, FrameOffset(48), high_register, false);
226*795d594fSAndroid Build Coastguard Worker   __ CreateJObject(method_register, FrameOffset(48), high_register, true);
227*795d594fSAndroid Build Coastguard Worker   __ CreateJObject(method_register, FrameOffset(0), high_register, true);
228*795d594fSAndroid Build Coastguard Worker   __ CreateJObject(method_register, FrameOffset(1028), high_register, true);
229*795d594fSAndroid Build Coastguard Worker   __ CreateJObject(high_register, FrameOffset(1028), high_register, true);
230*795d594fSAndroid Build Coastguard Worker 
231*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<JNIMacroLabel> exception_slow_path = __ CreateLabel();
232*795d594fSAndroid Build Coastguard Worker   __ ExceptionPoll(exception_slow_path.get());
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker   // Push the target out of range of branch emitted by ExceptionPoll.
235*795d594fSAndroid Build Coastguard Worker   for (int i = 0; i < 64; i++) {
236*795d594fSAndroid Build Coastguard Worker     __ Store(FrameOffset(2047), scratch_register, 4);
237*795d594fSAndroid Build Coastguard Worker   }
238*795d594fSAndroid Build Coastguard Worker 
239*795d594fSAndroid Build Coastguard Worker   __ DecreaseFrameSize(4096);
240*795d594fSAndroid Build Coastguard Worker   __ DecreaseFrameSize(32);
241*795d594fSAndroid Build Coastguard Worker   __ RemoveFrame(frame_size, callee_save_regs, /* may_suspend= */ true);
242*795d594fSAndroid Build Coastguard Worker 
243*795d594fSAndroid Build Coastguard Worker   __ Bind(exception_slow_path.get());
244*795d594fSAndroid Build Coastguard Worker   __ DeliverPendingException();
245*795d594fSAndroid Build Coastguard Worker 
246*795d594fSAndroid Build Coastguard Worker   EmitAndCheck("VixlJniHelpers", VixlJniHelpersResults);
247*795d594fSAndroid Build Coastguard Worker }
248*795d594fSAndroid Build Coastguard Worker 
249*795d594fSAndroid Build Coastguard Worker #undef __
250*795d594fSAndroid Build Coastguard Worker 
251*795d594fSAndroid Build Coastguard Worker // TODO: Avoid these macros.
252*795d594fSAndroid Build Coastguard Worker #define R0 vixl::aarch32::r0
253*795d594fSAndroid Build Coastguard Worker #define R2 vixl::aarch32::r2
254*795d594fSAndroid Build Coastguard Worker #define R4 vixl::aarch32::r4
255*795d594fSAndroid Build Coastguard Worker #define R12 vixl::aarch32::r12
256*795d594fSAndroid Build Coastguard Worker 
257*795d594fSAndroid Build Coastguard Worker #define __ assembler.asm_.
258*795d594fSAndroid Build Coastguard Worker 
TEST_F(ArmVIXLAssemblerTest,VixlLoadFromOffset)259*795d594fSAndroid Build Coastguard Worker TEST_F(ArmVIXLAssemblerTest, VixlLoadFromOffset) {
260*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWord, R2, R4, 12);
261*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWord, R2, R4, 0xfff);
262*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWord, R2, R4, 0x1000);
263*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWord, R2, R4, 0x1000a4);
264*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWord, R2, R4, 0x101000);
265*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWord, R4, R4, 0x101000);
266*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 12);
267*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0xfff);
268*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0x1000);
269*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0x1000a4);
270*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0x101000);
271*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadUnsignedHalfword, R4, R4, 0x101000);
272*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWordPair, R2, R4, 12);
273*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWordPair, R2, R4, 0x3fc);
274*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWordPair, R2, R4, 0x400);
275*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWordPair, R2, R4, 0x400a4);
276*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWordPair, R2, R4, 0x40400);
277*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWordPair, R4, R4, 0x40400);
278*795d594fSAndroid Build Coastguard Worker 
279*795d594fSAndroid Build Coastguard Worker   vixl::aarch32::UseScratchRegisterScope temps(assembler.asm_.GetVIXLAssembler());
280*795d594fSAndroid Build Coastguard Worker   temps.Exclude(R12);
281*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWord, R0, R12, 12);  // 32-bit because of R12.
282*795d594fSAndroid Build Coastguard Worker   temps.Include(R12);
283*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadWord, R2, R4, 0xa4 - 0x100000);
284*795d594fSAndroid Build Coastguard Worker 
285*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadSignedByte, R2, R4, 12);
286*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadUnsignedByte, R2, R4, 12);
287*795d594fSAndroid Build Coastguard Worker   __ LoadFromOffset(kLoadSignedHalfword, R2, R4, 12);
288*795d594fSAndroid Build Coastguard Worker 
289*795d594fSAndroid Build Coastguard Worker   EmitAndCheck("VixlLoadFromOffset", VixlLoadFromOffsetResults);
290*795d594fSAndroid Build Coastguard Worker }
291*795d594fSAndroid Build Coastguard Worker 
TEST_F(ArmVIXLAssemblerTest,VixlStoreToOffset)292*795d594fSAndroid Build Coastguard Worker TEST_F(ArmVIXLAssemblerTest, VixlStoreToOffset) {
293*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWord, R2, R4, 12);
294*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWord, R2, R4, 0xfff);
295*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWord, R2, R4, 0x1000);
296*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWord, R2, R4, 0x1000a4);
297*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWord, R2, R4, 0x101000);
298*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWord, R4, R4, 0x101000);
299*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreHalfword, R2, R4, 12);
300*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreHalfword, R2, R4, 0xfff);
301*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreHalfword, R2, R4, 0x1000);
302*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreHalfword, R2, R4, 0x1000a4);
303*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreHalfword, R2, R4, 0x101000);
304*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreHalfword, R4, R4, 0x101000);
305*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWordPair, R2, R4, 12);
306*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWordPair, R2, R4, 0x3fc);
307*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWordPair, R2, R4, 0x400);
308*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWordPair, R2, R4, 0x400a4);
309*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWordPair, R2, R4, 0x40400);
310*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWordPair, R4, R4, 0x40400);
311*795d594fSAndroid Build Coastguard Worker 
312*795d594fSAndroid Build Coastguard Worker   vixl::aarch32::UseScratchRegisterScope temps(assembler.asm_.GetVIXLAssembler());
313*795d594fSAndroid Build Coastguard Worker   temps.Exclude(R12);
314*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWord, R0, R12, 12);  // 32-bit because of R12.
315*795d594fSAndroid Build Coastguard Worker   temps.Include(R12);
316*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreWord, R2, R4, 0xa4 - 0x100000);
317*795d594fSAndroid Build Coastguard Worker 
318*795d594fSAndroid Build Coastguard Worker   __ StoreToOffset(kStoreByte, R2, R4, 12);
319*795d594fSAndroid Build Coastguard Worker 
320*795d594fSAndroid Build Coastguard Worker   EmitAndCheck("VixlStoreToOffset", VixlStoreToOffsetResults);
321*795d594fSAndroid Build Coastguard Worker }
322*795d594fSAndroid Build Coastguard Worker 
323*795d594fSAndroid Build Coastguard Worker #undef __
324*795d594fSAndroid Build Coastguard Worker }  // namespace arm
325*795d594fSAndroid Build Coastguard Worker }  // namespace art
326