assembler_thumb2_test.cc revision 513ea0c203a86e9d81a8630b56cb62704e126cc2
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "assembler_thumb2.h"
18
19#include "base/stl_util.h"
20#include "utils/assembler_test.h"
21
22namespace art {
23
24class AssemblerThumb2Test : public AssemblerTest<arm::Thumb2Assembler,
25                                                 arm::Register, arm::SRegister,
26                                                 uint32_t> {
27 protected:
28  std::string GetArchitectureString() OVERRIDE {
29    return "arm";
30  }
31
32  std::string GetAssemblerParameters() OVERRIDE {
33    return " -march=armv7-a -mcpu=cortex-a15 -mfpu=neon -mthumb";
34  }
35
36  const char* GetAssemblyHeader() OVERRIDE {
37    return kThumb2AssemblyHeader;
38  }
39
40  std::string GetDisassembleParameters() OVERRIDE {
41    return " -D -bbinary -marm --disassembler-options=force-thumb --no-show-raw-insn";
42  }
43
44  void SetUpHelpers() OVERRIDE {
45    if (registers_.size() == 0) {
46      registers_.insert(end(registers_),
47                        {  // NOLINT(whitespace/braces)
48                          new arm::Register(arm::R0),
49                          new arm::Register(arm::R1),
50                          new arm::Register(arm::R2),
51                          new arm::Register(arm::R3),
52                          new arm::Register(arm::R4),
53                          new arm::Register(arm::R5),
54                          new arm::Register(arm::R6),
55                          new arm::Register(arm::R7),
56                          new arm::Register(arm::R8),
57                          new arm::Register(arm::R9),
58                          new arm::Register(arm::R10),
59                          new arm::Register(arm::R11),
60                          new arm::Register(arm::R12),
61                          new arm::Register(arm::R13),
62                          new arm::Register(arm::R14),
63                          new arm::Register(arm::R15)
64                        });
65    }
66  }
67
68  void TearDown() OVERRIDE {
69    AssemblerTest::TearDown();
70    STLDeleteElements(&registers_);
71  }
72
73  std::vector<arm::Register*> GetRegisters() OVERRIDE {
74    return registers_;
75  }
76
77  uint32_t CreateImmediate(int64_t imm_value) OVERRIDE {
78    return imm_value;
79  }
80
81 private:
82  std::vector<arm::Register*> registers_;
83
84  static constexpr const char* kThumb2AssemblyHeader = ".syntax unified\n.thumb\n";
85};
86
87
88TEST_F(AssemblerThumb2Test, Toolchain) {
89  EXPECT_TRUE(CheckTools());
90}
91
92
93TEST_F(AssemblerThumb2Test, Sbfx) {
94  GetAssembler()->sbfx(arm::R0, arm::R1, 0, 1);
95  GetAssembler()->sbfx(arm::R0, arm::R1, 0, 8);
96  GetAssembler()->sbfx(arm::R0, arm::R1, 0, 16);
97  GetAssembler()->sbfx(arm::R0, arm::R1, 0, 32);
98
99  GetAssembler()->sbfx(arm::R0, arm::R1, 8, 1);
100  GetAssembler()->sbfx(arm::R0, arm::R1, 8, 8);
101  GetAssembler()->sbfx(arm::R0, arm::R1, 8, 16);
102  GetAssembler()->sbfx(arm::R0, arm::R1, 8, 24);
103
104  GetAssembler()->sbfx(arm::R0, arm::R1, 16, 1);
105  GetAssembler()->sbfx(arm::R0, arm::R1, 16, 8);
106  GetAssembler()->sbfx(arm::R0, arm::R1, 16, 16);
107
108  GetAssembler()->sbfx(arm::R0, arm::R1, 31, 1);
109
110  const char* expected =
111      "sbfx r0, r1, #0, #1\n"
112      "sbfx r0, r1, #0, #8\n"
113      "sbfx r0, r1, #0, #16\n"
114      "sbfx r0, r1, #0, #32\n"
115
116      "sbfx r0, r1, #8, #1\n"
117      "sbfx r0, r1, #8, #8\n"
118      "sbfx r0, r1, #8, #16\n"
119      "sbfx r0, r1, #8, #24\n"
120
121      "sbfx r0, r1, #16, #1\n"
122      "sbfx r0, r1, #16, #8\n"
123      "sbfx r0, r1, #16, #16\n"
124
125      "sbfx r0, r1, #31, #1\n";
126  DriverStr(expected, "sbfx");
127}
128
129TEST_F(AssemblerThumb2Test, Ubfx) {
130  GetAssembler()->ubfx(arm::R0, arm::R1, 0, 1);
131  GetAssembler()->ubfx(arm::R0, arm::R1, 0, 8);
132  GetAssembler()->ubfx(arm::R0, arm::R1, 0, 16);
133  GetAssembler()->ubfx(arm::R0, arm::R1, 0, 32);
134
135  GetAssembler()->ubfx(arm::R0, arm::R1, 8, 1);
136  GetAssembler()->ubfx(arm::R0, arm::R1, 8, 8);
137  GetAssembler()->ubfx(arm::R0, arm::R1, 8, 16);
138  GetAssembler()->ubfx(arm::R0, arm::R1, 8, 24);
139
140  GetAssembler()->ubfx(arm::R0, arm::R1, 16, 1);
141  GetAssembler()->ubfx(arm::R0, arm::R1, 16, 8);
142  GetAssembler()->ubfx(arm::R0, arm::R1, 16, 16);
143
144  GetAssembler()->ubfx(arm::R0, arm::R1, 31, 1);
145
146  const char* expected =
147      "ubfx r0, r1, #0, #1\n"
148      "ubfx r0, r1, #0, #8\n"
149      "ubfx r0, r1, #0, #16\n"
150      "ubfx r0, r1, #0, #32\n"
151
152      "ubfx r0, r1, #8, #1\n"
153      "ubfx r0, r1, #8, #8\n"
154      "ubfx r0, r1, #8, #16\n"
155      "ubfx r0, r1, #8, #24\n"
156
157      "ubfx r0, r1, #16, #1\n"
158      "ubfx r0, r1, #16, #8\n"
159      "ubfx r0, r1, #16, #16\n"
160
161      "ubfx r0, r1, #31, #1\n";
162  DriverStr(expected, "ubfx");
163}
164
165TEST_F(AssemblerThumb2Test, Vmstat) {
166  GetAssembler()->vmstat();
167
168  const char* expected = "vmrs APSR_nzcv, FPSCR\n";
169
170  DriverStr(expected, "vmrs");
171}
172
173TEST_F(AssemblerThumb2Test, ldrexd) {
174  GetAssembler()->ldrexd(arm::R0, arm::R1, arm::R0);
175  GetAssembler()->ldrexd(arm::R0, arm::R1, arm::R1);
176  GetAssembler()->ldrexd(arm::R0, arm::R1, arm::R2);
177  GetAssembler()->ldrexd(arm::R5, arm::R3, arm::R7);
178
179  const char* expected =
180      "ldrexd r0, r1, [r0]\n"
181      "ldrexd r0, r1, [r1]\n"
182      "ldrexd r0, r1, [r2]\n"
183      "ldrexd r5, r3, [r7]\n";
184  DriverStr(expected, "ldrexd");
185}
186
187TEST_F(AssemblerThumb2Test, strexd) {
188  GetAssembler()->strexd(arm::R9, arm::R0, arm::R1, arm::R0);
189  GetAssembler()->strexd(arm::R9, arm::R0, arm::R1, arm::R1);
190  GetAssembler()->strexd(arm::R9, arm::R0, arm::R1, arm::R2);
191  GetAssembler()->strexd(arm::R9, arm::R5, arm::R3, arm::R7);
192
193  const char* expected =
194      "strexd r9, r0, r1, [r0]\n"
195      "strexd r9, r0, r1, [r1]\n"
196      "strexd r9, r0, r1, [r2]\n"
197      "strexd r9, r5, r3, [r7]\n";
198  DriverStr(expected, "strexd");
199}
200
201TEST_F(AssemblerThumb2Test, eor) {
202#define __ GetAssembler()->
203  __ eor(arm::R1, arm::R1, arm::ShifterOperand(arm::R0));
204  __ eor(arm::R1, arm::R0, arm::ShifterOperand(arm::R1));
205  __ eor(arm::R1, arm::R8, arm::ShifterOperand(arm::R0));
206  __ eor(arm::R8, arm::R1, arm::ShifterOperand(arm::R0));
207  __ eor(arm::R1, arm::R0, arm::ShifterOperand(arm::R8));
208
209  const char* expected =
210      "eors r1, r0\n"
211      "eor r1, r0, r1\n"
212      "eor r1, r8, r0\n"
213      "eor r8, r1, r0\n"
214      "eor r1, r0, r8\n";
215  DriverStr(expected, "abs");
216}
217
218}  // namespace art
219