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>{, #{+/-}<imm_3>}] ; A1
30            // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
31            // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
32    "Ldrb", // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
33            // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
34            // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
35    "Str",  // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
36            // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
37            // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
38    "Strb"  // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
39            // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
40            // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; 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": "offset",
66            "type": "OffsetLowerThan4096"
67          },
68          {
69            "name": "addr_mode",
70            "type": "AddressingMode"
71          }
72        ]
73      }
74    ],
75    "inputs": [
76      {
77        "name": "apsr",
78        "type": "NZCV"
79      },
80      {
81        "name": "rd",
82        "type": "Register"
83      },
84      {
85        "name": "memop",
86        "type": "MemOperand"
87      }
88    ]
89  },
90  "test-files": [
91    {
92      "type": "assembler",
93      "test-cases": [
94        {
95          "name": "Registers",
96          "operands": [
97            "cond", "rd", "rn"
98          ],
99          "operand-limit": 100
100        },
101        {
102          "name": "MemOperandsOffset",
103          "operands": [
104            "rn", "sign", "offset", "addr_mode"
105          ],
106          "operand-filter": "addr_mode == 'Offset'",
107          "operand-limit": 200
108        },
109        {
110          "name": "MemOperandsWriteBack",
111          "operands": [
112            "rd", "rn", "sign", "offset", "addr_mode"
113          ],
114          "operand-filter": "addr_mode != 'Offset' and rd != rn",
115          "operand-limit": 400
116        }
117      ]
118    },
119    {
120      // TODO: The simulator tests do not support the case where `rd` ==
121      // `rn`. See `data_types.MemOperand.Epilogue()` for details.
122      "type": "simulator",
123      "test-cases": [
124        {
125          "name": "Condition",
126          "operands": [
127            "cond", "rd", "rn"
128          ],
129          "operand-filter": "rd == 'r0' and rn == 'r1'",
130          "inputs": [
131            "apsr"
132          ]
133        },
134        {
135          "name": "PositiveOffset",
136          "operands": [
137            "rd", "rn", "sign", "offset", "addr_mode"
138          ],
139          "operand-filter": "sign == 'plus' and addr_mode == 'Offset' and rd != rn",
140          "operand-limit": 100,
141          "inputs": [
142            "rd", "memop"
143          ],
144          "input-limit": 10
145        },
146        {
147          "name": "NegativeOffset",
148          "operands": [
149            "rd", "rn", "sign", "offset", "addr_mode"
150          ],
151          "operand-filter": "sign == 'minus' and addr_mode == 'Offset' and rd != rn",
152          "operand-limit": 100,
153          "inputs": [
154            "rd", "memop"
155          ],
156          "input-limit": 10
157        },
158        {
159          "name": "PositivePostIndex",
160          "operands": [
161            "rd", "rn", "sign", "offset", "addr_mode"
162          ],
163          "operand-filter": "sign == 'plus' and addr_mode == 'PostIndex' and rd != rn",
164          "operand-limit": 100,
165          "inputs": [
166            "rd", "memop"
167          ],
168          "input-limit": 10
169        },
170        {
171          "name": "NegativePostIndex",
172          "operands": [
173            "rd", "rn", "sign", "offset", "addr_mode"
174          ],
175          "operand-filter": "sign == 'minus' and addr_mode == 'PostIndex' and rd != rn",
176          "operand-limit": 100,
177          "inputs": [
178            "rd", "memop"
179          ],
180          "input-limit": 10
181        },
182        {
183          "name": "PositivePreIndex",
184          "operands": [
185            "rd", "rn", "sign", "offset", "addr_mode"
186          ],
187          "operand-filter": "sign == 'plus' and addr_mode == 'PreIndex' and rd != rn",
188          "operand-limit": 100,
189          "inputs": [
190            "rd", "memop"
191          ],
192          "input-limit": 10
193        },
194        {
195          "name": "NegativePreIndex",
196          "operands": [
197            "rd", "rn", "sign", "offset", "addr_mode"
198          ],
199          "operand-filter": "sign == 'minus' and addr_mode == 'PreIndex' and rd != rn",
200          "operand-limit": 100,
201          "inputs": [
202            "rd", "memop"
203          ],
204          "input-limit": 10
205        }
206      ]
207    }
208  ]
209}
210