1// Copyright 2016, VIXL authors
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7//   * Redistributions of source code must retain the above copyright notice,
8//     this list of conditions and the following disclaimer.
9//   * Redistributions in binary form must reproduce the above copyright notice,
10//     this list of conditions and the following disclaimer in the documentation
11//     and/or other materials provided with the distribution.
12//   * Neither the name of ARM Limited nor the names of its contributors may be
13//     used to endorse or promote products derived from this software without
14//     specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24// OR TORT (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.
26
27{
28  "mnemonics": [
29    "Ldr",  // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
30            // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
31            // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
32    "Ldrb", // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
33            // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
34            // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
35    "Str",  // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
36            // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
37            // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
38    "Strb"  // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
39            // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
40            // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
41  ],
42  "description": {
43    "operands": [
44      {
45        "name": "cond",
46        "type": "Condition"
47      },
48      {
49        "name": "rd",
50        "type": "AllRegistersButPC"
51      },
52      {
53        "name": "memop",
54        "wrapper": "MemOperand",
55        "operands": [
56          {
57            "name": "rn",
58            "type": "AllRegistersButPC"
59          },
60          {
61            "name": "sign",
62            "type": "Sign"
63          },
64          {
65            "name": "rm",
66            "type": "AllRegistersButPC"
67          },
68          {
69            "name": "shift",
70            "type": "Shift1To31"
71          },
72          {
73            "name": "amount",
74            "type": "ShiftAmount1To31"
75          },
76          {
77            "name": "addr_mode",
78            "type": "AddressingMode"
79          }
80        ]
81      }
82    ],
83    "inputs": [
84      {
85        "name": "apsr",
86        "type": "NZCV"
87      },
88      {
89        "name": "rd",
90        "type": "Register"
91      },
92      {
93        "name": "rm",
94        "type": "RegisterOffsetLowerThan4096"
95      },
96      {
97        "name": "memop",
98        "type": "MemOperand"
99      }
100    ]
101  },
102  "test-files": [
103    {
104      "type": "assembler",
105      "test-cases": [
106        {
107          "name": "Registers",
108          "operands": [
109            "cond", "rd", "rn", "rm"
110          ],
111          "operand-limit": 100
112        },
113        {
114          "name": "MemOperandsOffset",
115          "operands": [
116            "rn", "sign", "rm", "shift", "amount", "addr_mode"
117          ],
118          "operand-filter": "addr_mode == 'Offset'",
119          "operand-limit": 200
120        },
121        {
122          "name": "MemOperandsWriteBack",
123          "operands": [
124            "rd", "rn", "sign", "rm", "shift", "amount", "addr_mode"
125          ],
126          "operand-filter": "addr_mode != 'Offset' and rd != rn",
127          "operand-limit": 400
128        }
129      ]
130    },
131    {
132      // TODO: The simulator tests do not support the case where `rd` ==
133      // `rn`. See `data_types.MemOperand.Epilogue()` for details.
134      "type": "simulator",
135      "test-cases": [
136        {
137          "name": "Condition",
138          "operands": [
139            "cond", "rd", "rn", "rm"
140          ],
141          "operand-filter": "rd == 'r0' and rn == 'r1' and rm == 'r8'",
142          "inputs": [
143            "apsr"
144          ]
145        },
146        {
147          "name": "PositiveOffset",
148          "operands": [
149            "rd", "rn", "sign", "rm", "shift", "amount", "addr_mode"
150          ],
151          "operand-filter": "sign == 'plus' and addr_mode == 'Offset' and rd != rm and rd != rn and rn != rm",
152          "operand-limit": 100,
153          "inputs": [
154            "memop", "rm"
155          ],
156          "input-limit": 10
157        },
158        {
159          "name": "NegativeOffset",
160          "operands": [
161            "rd", "rn", "sign", "rm", "shift", "amount", "addr_mode"
162          ],
163          "operand-filter": "sign == 'minus' and addr_mode == 'Offset' and rd != rm and rd != rn and rn != rm",
164          "operand-limit": 100,
165          "inputs": [
166            "memop", "rm"
167          ],
168          "input-limit": 10
169        },
170        {
171          "name": "PositivePostIndex",
172          "operands": [
173            "rd", "rn", "sign", "rm", "shift", "amount", "addr_mode"
174          ],
175          "operand-filter": "sign == 'plus' and addr_mode == 'PostIndex' and rd != rm and rd != rn and rn != rm",
176          "operand-limit": 100,
177          "inputs": [
178            "memop", "rm"
179          ],
180          "input-limit": 10
181        },
182        {
183          "name": "NegativePostIndex",
184          "operands": [
185            "rd", "rn", "sign", "rm", "shift", "amount", "addr_mode"
186          ],
187          "operand-filter": "sign == 'minus' and addr_mode == 'PostIndex' and rd != rm and rd != rn and rn != rm",
188          "operand-limit": 100,
189          "inputs": [
190            "memop", "rm"
191          ],
192          "input-limit": 10
193        },
194        {
195          "name": "PositivePreIndex",
196          "operands": [
197            "rd", "rn", "sign", "rm", "shift", "amount", "addr_mode"
198          ],
199          "operand-filter": "sign == 'plus' and addr_mode == 'PreIndex' and rd != rm and rd != rn and rn != rm",
200          "operand-limit": 100,
201          "inputs": [
202            "memop", "rm"
203          ],
204          "input-limit": 10
205        },
206        {
207          "name": "NegativePreIndex",
208          "operands": [
209            "rd", "rn", "sign", "rm", "shift", "amount", "addr_mode"
210          ],
211          "operand-filter": "sign == 'minus' and addr_mode == 'PreIndex' and rd != rm and rd != rn and rn != rm",
212          "operand-limit": 100,
213          "inputs": [
214            "memop", "rm"
215          ],
216          "input-limit": 10
217        }
218      ]
219    }
220  ]
221}
222