]> git.saurik.com Git - apple/javascriptcore.git/blame - offlineasm/arm.rb
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / offlineasm / arm.rb
CommitLineData
93a37866
A
1# Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
2# Copyright (C) 2013 University of Szeged. 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
6# are met:
7# 1. Redistributions of source code must retain the above copyright
8# notice, this list of conditions and the following disclaimer.
9# 2. Redistributions in binary form must reproduce the above copyright
10# notice, this list of conditions and the following disclaimer in the
11# documentation and/or other materials provided with the distribution.
12#
13# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23# THE POSSIBILITY OF SUCH DAMAGE.
24
25require "config"
26require "ast"
27require "opt"
28require "risc"
29
30def isARMv7
31 case $activeBackend
32 when "ARMv7"
33 true
34 when "ARMv7_TRADITIONAL", "ARM"
35 false
36 else
37 raise "bad value for $activeBackend: #{$activeBackend}"
38 end
39end
40
41def isARMv7Traditional
42 case $activeBackend
43 when "ARMv7_TRADITIONAL"
44 true
45 when "ARMv7", "ARM"
46 false
47 else
48 raise "bad value for $activeBackend: #{$activeBackend}"
49 end
50end
51
52class Node
53 def armSingle
54 doubleOperand = armOperand
55 raise "Bogus register name #{doubleOperand}" unless doubleOperand =~ /^d/
56 "s" + ($~.post_match.to_i * 2).to_s
57 end
58end
59
60class SpecialRegister
61 def armOperand
62 @name
63 end
64end
65
81345200 66ARM_EXTRA_GPRS = [SpecialRegister.new("r6"), SpecialRegister.new("r10"), SpecialRegister.new("r12")]
93a37866
A
67ARM_EXTRA_FPRS = [SpecialRegister.new("d7")]
68ARM_SCRATCH_FPR = SpecialRegister.new("d6")
69
70def armMoveImmediate(value, register)
71 # Currently we only handle the simple cases, and fall back to mov/movt for the complex ones.
81345200
A
72 if value.is_a? String
73 $asm.puts "mov #{register.armOperand}, (#{value})"
74 elsif value >= 0 && value < 256
93a37866
A
75 $asm.puts "mov #{register.armOperand}, \##{value}"
76 elsif (~value) >= 0 && (~value) < 256
77 $asm.puts "mvn #{register.armOperand}, \##{~value}"
78 elsif isARMv7 or isARMv7Traditional
79 $asm.puts "movw #{register.armOperand}, \##{value & 0xffff}"
80 if (value & 0xffff0000) != 0
81 $asm.puts "movt #{register.armOperand}, \##{(value >> 16) & 0xffff}"
82 end
83 else
84 $asm.puts "ldr #{register.armOperand}, =#{value}"
85 end
86end
87
88class RegisterID
89 def armOperand
90 case name
91 when "t0", "a0", "r0"
92 "r0"
93 when "t1", "a1", "r1"
94 "r1"
95 when "t2", "a2"
96 "r2"
97 when "a3"
98 "r3"
99 when "t3"
100 "r4"
101 when "t4"
81345200
A
102 "r8"
103 when "t5"
104 "r9"
93a37866 105 when "cfr"
81345200 106 isARMv7 ? "r7" : "r11"
93a37866
A
107 when "lr"
108 "lr"
109 when "sp"
110 "sp"
81345200
A
111 when "pc"
112 "pc"
93a37866
A
113 else
114 raise "Bad register #{name} for ARM at #{codeOriginString}"
115 end
116 end
117end
118
119class FPRegisterID
120 def armOperand
121 case name
122 when "ft0", "fr"
123 "d0"
124 when "ft1"
125 "d1"
126 when "ft2"
127 "d2"
128 when "ft3"
129 "d3"
130 when "ft4"
131 "d4"
132 when "ft5"
133 "d5"
134 else
135 raise "Bad register #{name} for ARM at #{codeOriginString}"
136 end
137 end
138end
139
140class Immediate
141 def armOperand
142 raise "Invalid immediate #{value} at #{codeOriginString}" if value < 0 or value > 255
143 "\##{value}"
144 end
145end
146
147class Address
148 def armOperand
149 raise "Bad offset at #{codeOriginString}" if offset.value < -0xff or offset.value > 0xfff
150 "[#{base.armOperand}, \##{offset.value}]"
151 end
152end
153
154class BaseIndex
155 def armOperand
156 raise "Bad offset at #{codeOriginString}" if offset.value != 0
157 "[#{base.armOperand}, #{index.armOperand}, lsl \##{scaleShift}]"
158 end
159end
160
161class AbsoluteAddress
162 def armOperand
163 raise "Unconverted absolute address at #{codeOriginString}"
164 end
165end
166
167#
168# Lea support.
169#
170
171class Address
172 def armEmitLea(destination)
173 if destination == base
174 $asm.puts "adds #{destination.armOperand}, \##{offset.value}"
175 else
176 $asm.puts "adds #{destination.armOperand}, #{base.armOperand}, \##{offset.value}"
177 end
178 end
179end
180
181class BaseIndex
182 def armEmitLea(destination)
183 raise "Malformed BaseIndex, offset should be zero at #{codeOriginString}" unless offset.value == 0
184 $asm.puts "add #{destination.armOperand}, #{base.armOperand}, #{index.armOperand}, lsl \##{scaleShift}"
185 end
186end
187
188# FIXME: we could support AbsoluteAddress for lea, but we don't.
189
190#
191# Actual lowering code follows.
192#
193
194class Sequence
195 def getModifiedListARM
196 raise unless $activeBackend == "ARM"
197 getModifiedListARMCommon
198 end
199
200 def getModifiedListARMv7
201 raise unless $activeBackend == "ARMv7"
202 getModifiedListARMCommon
203 end
204
205 def getModifiedListARMv7_TRADITIONAL
206 raise unless $activeBackend == "ARMv7_TRADITIONAL"
207 getModifiedListARMCommon
208 end
209
210 def getModifiedListARMCommon
211 result = @list
212 result = riscLowerSimpleBranchOps(result)
213 result = riscLowerHardBranchOps(result)
214 result = riscLowerShiftOps(result)
215 result = riscLowerMalformedAddresses(result) {
216 | node, address |
217 if address.is_a? BaseIndex
218 address.offset.value == 0
219 elsif address.is_a? Address
220 (-0xff..0xfff).include? address.offset.value
221 else
222 false
223 end
224 }
225 result = riscLowerMalformedAddressesDouble(result)
226 result = riscLowerMisplacedImmediates(result, ["storeb", "storei", "storep", "storeq"])
227 result = riscLowerMalformedImmediates(result, 0..0xff)
228 result = riscLowerMisplacedAddresses(result)
229 result = riscLowerRegisterReuse(result)
230 result = assignRegistersToTemporaries(result, :gpr, ARM_EXTRA_GPRS)
231 result = assignRegistersToTemporaries(result, :fpr, ARM_EXTRA_FPRS)
232 return result
233 end
234end
235
236def armOperands(operands)
237 operands.map{|v| v.armOperand}.join(", ")
238end
239
240def armFlippedOperands(operands)
241 armOperands([operands[-1]] + operands[0..-2])
242end
243
244def emitArmCompact(opcode2, opcode3, operands)
245 if operands.size == 3
246 $asm.puts "#{opcode3} #{armFlippedOperands(operands)}"
247 else
248 raise unless operands.size == 2
249 raise unless operands[1].register?
250 if operands[0].immediate?
251 $asm.puts "#{opcode3} #{operands[1].armOperand}, #{operands[1].armOperand}, #{operands[0].armOperand}"
252 else
253 $asm.puts "#{opcode2} #{armFlippedOperands(operands)}"
254 end
255 end
256end
257
258def emitArm(opcode, operands)
259 if operands.size == 3
260 $asm.puts "#{opcode} #{armFlippedOperands(operands)}"
261 else
262 raise unless operands.size == 2
263 $asm.puts "#{opcode} #{operands[1].armOperand}, #{operands[1].armOperand}, #{operands[0].armOperand}"
264 end
265end
266
267def emitArmDoubleBranch(branchOpcode, operands)
268 $asm.puts "vcmpe.f64 #{armOperands(operands[0..1])}"
269 $asm.puts "vmrs apsr_nzcv, fpscr"
270 $asm.puts "#{branchOpcode} #{operands[2].asmLabel}"
271end
272
273def emitArmTest(operands)
274 value = operands[0]
275 case operands.size
276 when 2
277 mask = Immediate.new(codeOrigin, -1)
278 when 3
279 mask = operands[1]
280 else
281 raise "Expected 2 or 3 operands but got #{operands.size} at #{codeOriginString}"
282 end
283
284 if mask.immediate? and mask.value == -1
285 $asm.puts "tst #{value.armOperand}, #{value.armOperand}"
286 else
287 $asm.puts "tst #{value.armOperand}, #{mask.armOperand}"
288 end
289end
290
291def emitArmCompare(operands, code)
292 $asm.puts "movs #{operands[2].armOperand}, \#0"
293 $asm.puts "cmp #{operands[0].armOperand}, #{operands[1].armOperand}"
294 $asm.puts "it #{code}"
295 $asm.puts "mov#{code} #{operands[2].armOperand}, \#1"
296end
297
298def emitArmTestSet(operands, code)
299 $asm.puts "movs #{operands[-1].armOperand}, \#0"
300 emitArmTest(operands)
301 $asm.puts "it #{code}"
302 $asm.puts "mov#{code} #{operands[-1].armOperand}, \#1"
303end
304
305class Instruction
306 def lowerARM
307 raise unless $activeBackend == "ARM"
308 lowerARMCommon
309 end
310
311 def lowerARMv7
312 raise unless $activeBackend == "ARMv7"
313 lowerARMCommon
314 end
315
316 def lowerARMv7_TRADITIONAL
317 raise unless $activeBackend == "ARMv7_TRADITIONAL"
318 lowerARMCommon
319 end
320
321 def lowerARMCommon
322 $asm.codeOrigin codeOriginString if $enableCodeOriginComments
323 $asm.annotation annotation if $enableInstrAnnotations
324
325 case opcode
326 when "addi", "addp", "addis", "addps"
327 if opcode == "addis" or opcode == "addps"
328 suffix = "s"
329 else
330 suffix = ""
331 end
332 if operands.size == 3 and operands[0].immediate?
333 raise unless operands[1].register?
334 raise unless operands[2].register?
335 if operands[0].value == 0 and suffix.empty?
336 unless operands[1] == operands[2]
337 $asm.puts "mov #{operands[2].armOperand}, #{operands[1].armOperand}"
338 end
339 else
340 $asm.puts "adds #{operands[2].armOperand}, #{operands[1].armOperand}, #{operands[0].armOperand}"
341 end
81345200 342 elsif operands.size == 3 and operands[0].register?
93a37866
A
343 raise unless operands[1].register?
344 raise unless operands[2].register?
345 $asm.puts "adds #{armFlippedOperands(operands)}"
346 else
347 if operands[0].immediate?
348 unless Immediate.new(nil, 0) == operands[0]
349 $asm.puts "adds #{armFlippedOperands(operands)}"
350 end
351 else
352 $asm.puts "add#{suffix} #{armFlippedOperands(operands)}"
353 end
354 end
355 when "andi", "andp"
356 emitArmCompact("ands", "and", operands)
357 when "ori", "orp"
358 emitArmCompact("orrs", "orr", operands)
359 when "oris"
360 emitArmCompact("orrs", "orrs", operands)
361 when "xori", "xorp"
362 emitArmCompact("eors", "eor", operands)
363 when "lshifti", "lshiftp"
364 emitArmCompact("lsls", "lsls", operands)
365 when "rshifti", "rshiftp"
366 emitArmCompact("asrs", "asrs", operands)
367 when "urshifti", "urshiftp"
368 emitArmCompact("lsrs", "lsrs", operands)
369 when "muli", "mulp"
370 emitArm("mul", operands)
371 when "subi", "subp", "subis"
372 emitArmCompact("subs", "subs", operands)
373 when "negi", "negp"
374 $asm.puts "rsbs #{operands[0].armOperand}, #{operands[0].armOperand}, \#0"
375 when "noti"
376 $asm.puts "mvns #{operands[0].armOperand}, #{operands[0].armOperand}"
377 when "loadi", "loadis", "loadp"
378 $asm.puts "ldr #{armFlippedOperands(operands)}"
379 when "storei", "storep"
380 $asm.puts "str #{armOperands(operands)}"
381 when "loadb"
382 $asm.puts "ldrb #{armFlippedOperands(operands)}"
383 when "loadbs"
384 $asm.puts "ldrsb.w #{armFlippedOperands(operands)}"
385 when "storeb"
386 $asm.puts "strb #{armOperands(operands)}"
387 when "loadh"
388 $asm.puts "ldrh #{armFlippedOperands(operands)}"
389 when "loadhs"
390 $asm.puts "ldrsh.w #{armFlippedOperands(operands)}"
391 when "storeh"
392 $asm.puts "strh #{armOperands(operands)}"
393 when "loadd"
394 $asm.puts "vldr.64 #{armFlippedOperands(operands)}"
395 when "stored"
396 $asm.puts "vstr.64 #{armOperands(operands)}"
397 when "addd"
398 emitArm("vadd.f64", operands)
399 when "divd"
400 emitArm("vdiv.f64", operands)
401 when "subd"
402 emitArm("vsub.f64", operands)
403 when "muld"
404 emitArm("vmul.f64", operands)
405 when "sqrtd"
406 $asm.puts "vsqrt.f64 #{armFlippedOperands(operands)}"
407 when "ci2d"
408 $asm.puts "vmov #{operands[1].armSingle}, #{operands[0].armOperand}"
409 $asm.puts "vcvt.f64.s32 #{operands[1].armOperand}, #{operands[1].armSingle}"
410 when "bdeq"
411 emitArmDoubleBranch("beq", operands)
412 when "bdneq"
413 $asm.puts "vcmpe.f64 #{armOperands(operands[0..1])}"
414 $asm.puts "vmrs apsr_nzcv, fpscr"
415 isUnordered = LocalLabel.unique("bdneq")
416 $asm.puts "bvs #{LocalLabelReference.new(codeOrigin, isUnordered).asmLabel}"
417 $asm.puts "bne #{operands[2].asmLabel}"
418 isUnordered.lower("ARM")
419 when "bdgt"
420 emitArmDoubleBranch("bgt", operands)
421 when "bdgteq"
422 emitArmDoubleBranch("bge", operands)
423 when "bdlt"
424 emitArmDoubleBranch("bmi", operands)
425 when "bdlteq"
426 emitArmDoubleBranch("bls", operands)
427 when "bdequn"
428 $asm.puts "vcmpe.f64 #{armOperands(operands[0..1])}"
429 $asm.puts "vmrs apsr_nzcv, fpscr"
430 $asm.puts "bvs #{operands[2].asmLabel}"
431 $asm.puts "beq #{operands[2].asmLabel}"
432 when "bdnequn"
433 emitArmDoubleBranch("bne", operands)
434 when "bdgtun"
435 emitArmDoubleBranch("bhi", operands)
436 when "bdgtequn"
437 emitArmDoubleBranch("bpl", operands)
438 when "bdltun"
439 emitArmDoubleBranch("blt", operands)
440 when "bdltequn"
441 emitArmDoubleBranch("ble", operands)
442 when "btd2i"
443 # FIXME: may be a good idea to just get rid of this instruction, since the interpreter
444 # currently does not use it.
445 raise "ARM does not support this opcode yet, #{codeOrigin}"
446 when "td2i"
447 $asm.puts "vcvt.s32.f64 #{ARM_SCRATCH_FPR.armSingle}, #{operands[0].armOperand}"
448 $asm.puts "vmov #{operands[1].armOperand}, #{ARM_SCRATCH_FPR.armSingle}"
449 when "bcd2i"
450 $asm.puts "vcvt.s32.f64 #{ARM_SCRATCH_FPR.armSingle}, #{operands[0].armOperand}"
451 $asm.puts "vmov #{operands[1].armOperand}, #{ARM_SCRATCH_FPR.armSingle}"
452 $asm.puts "vcvt.f64.s32 #{ARM_SCRATCH_FPR.armOperand}, #{ARM_SCRATCH_FPR.armSingle}"
453 emitArmDoubleBranch("bne", [ARM_SCRATCH_FPR, operands[0], operands[2]])
454 $asm.puts "tst #{operands[1].armOperand}, #{operands[1].armOperand}"
455 $asm.puts "beq #{operands[2].asmLabel}"
456 when "movdz"
457 # FIXME: either support this or remove it.
458 raise "ARM does not support this opcode yet, #{codeOrigin}"
459 when "pop"
81345200
A
460 operands.each {
461 | op |
462 $asm.puts "pop { #{op.armOperand} }"
463 }
93a37866 464 when "push"
81345200
A
465 operands.each {
466 | op |
467 $asm.puts "push { #{op.armOperand} }"
468 }
93a37866
A
469 when "move"
470 if operands[0].immediate?
471 armMoveImmediate(operands[0].value, operands[1])
472 else
473 $asm.puts "mov #{armFlippedOperands(operands)}"
474 end
81345200
A
475 when "mvlbl"
476 $asm.puts "movw #{operands[1].armOperand}, \#:lower16:#{operands[0].value}"
477 $asm.puts "movt #{operands[1].armOperand}, \#:upper16:#{operands[0].value}"
93a37866
A
478 when "nop"
479 $asm.puts "nop"
480 when "bieq", "bpeq", "bbeq"
481 if Immediate.new(nil, 0) == operands[0]
482 $asm.puts "tst #{operands[1].armOperand}, #{operands[1].armOperand}"
483 elsif Immediate.new(nil, 0) == operands[1]
484 $asm.puts "tst #{operands[0].armOperand}, #{operands[0].armOperand}"
485 else
486 $asm.puts "cmp #{armOperands(operands[0..1])}"
487 end
488 $asm.puts "beq #{operands[2].asmLabel}"
489 when "bineq", "bpneq", "bbneq"
490 if Immediate.new(nil, 0) == operands[0]
491 $asm.puts "tst #{operands[1].armOperand}, #{operands[1].armOperand}"
492 elsif Immediate.new(nil, 0) == operands[1]
493 $asm.puts "tst #{operands[0].armOperand}, #{operands[0].armOperand}"
494 else
495 $asm.puts "cmp #{armOperands(operands[0..1])}"
496 end
497 $asm.puts "bne #{operands[2].asmLabel}"
498 when "bia", "bpa", "bba"
499 $asm.puts "cmp #{armOperands(operands[0..1])}"
500 $asm.puts "bhi #{operands[2].asmLabel}"
501 when "biaeq", "bpaeq", "bbaeq"
502 $asm.puts "cmp #{armOperands(operands[0..1])}"
503 $asm.puts "bhs #{operands[2].asmLabel}"
504 when "bib", "bpb", "bbb"
505 $asm.puts "cmp #{armOperands(operands[0..1])}"
506 $asm.puts "blo #{operands[2].asmLabel}"
507 when "bibeq", "bpbeq", "bbbeq"
508 $asm.puts "cmp #{armOperands(operands[0..1])}"
509 $asm.puts "bls #{operands[2].asmLabel}"
510 when "bigt", "bpgt", "bbgt"
511 $asm.puts "cmp #{armOperands(operands[0..1])}"
512 $asm.puts "bgt #{operands[2].asmLabel}"
513 when "bigteq", "bpgteq", "bbgteq"
514 $asm.puts "cmp #{armOperands(operands[0..1])}"
515 $asm.puts "bge #{operands[2].asmLabel}"
516 when "bilt", "bplt", "bblt"
517 $asm.puts "cmp #{armOperands(operands[0..1])}"
518 $asm.puts "blt #{operands[2].asmLabel}"
519 when "bilteq", "bplteq", "bblteq"
520 $asm.puts "cmp #{armOperands(operands[0..1])}"
521 $asm.puts "ble #{operands[2].asmLabel}"
522 when "btiz", "btpz", "btbz"
523 emitArmTest(operands)
524 $asm.puts "beq #{operands[-1].asmLabel}"
525 when "btinz", "btpnz", "btbnz"
526 emitArmTest(operands)
527 $asm.puts "bne #{operands[-1].asmLabel}"
528 when "btis", "btps", "btbs"
529 emitArmTest(operands)
530 $asm.puts "bmi #{operands[-1].asmLabel}"
531 when "jmp"
532 if operands[0].label?
533 $asm.puts "b #{operands[0].asmLabel}"
534 else
535 $asm.puts "mov pc, #{operands[0].armOperand}"
536 end
537 if not isARMv7 and not isARMv7Traditional
538 $asm.puts ".ltorg"
539 end
540 when "call"
541 if operands[0].label?
542 $asm.puts "blx #{operands[0].asmLabel}"
543 else
544 $asm.puts "blx #{operands[0].armOperand}"
545 end
546 when "break"
547 $asm.puts "bkpt #0"
548 when "ret"
549 $asm.puts "bx lr"
550 when "cieq", "cpeq", "cbeq"
551 emitArmCompare(operands, "eq")
552 when "cineq", "cpneq", "cbneq"
553 emitArmCompare(operands, "ne")
554 when "cia", "cpa", "cba"
555 emitArmCompare(operands, "hi")
556 when "ciaeq", "cpaeq", "cbaeq"
557 emitArmCompare(operands, "hs")
558 when "cib", "cpb", "cbb"
559 emitArmCompare(operands, "lo")
560 when "cibeq", "cpbeq", "cbbeq"
561 emitArmCompare(operands, "ls")
562 when "cigt", "cpgt", "cbgt"
563 emitArmCompare(operands, "gt")
564 when "cigteq", "cpgteq", "cbgteq"
565 emitArmCompare(operands, "ge")
566 when "cilt", "cplt", "cblt"
567 emitArmCompare(operands, "lt")
568 when "cilteq", "cplteq", "cblteq"
569 emitArmCompare(operands, "le")
570 when "tis", "tbs", "tps"
571 emitArmTestSet(operands, "mi")
572 when "tiz", "tbz", "tpz"
573 emitArmTestSet(operands, "eq")
574 when "tinz", "tbnz", "tpnz"
575 emitArmTestSet(operands, "ne")
576 when "peek"
577 $asm.puts "ldr #{operands[1].armOperand}, [sp, \##{operands[0].value * 4}]"
578 when "poke"
579 $asm.puts "str #{operands[1].armOperand}, [sp, \##{operands[0].value * 4}]"
580 when "fii2d"
581 $asm.puts "vmov #{operands[2].armOperand}, #{operands[0].armOperand}, #{operands[1].armOperand}"
582 when "fd2ii"
583 $asm.puts "vmov #{operands[1].armOperand}, #{operands[2].armOperand}, #{operands[0].armOperand}"
584 when "bo"
585 $asm.puts "bvs #{operands[0].asmLabel}"
586 when "bs"
587 $asm.puts "bmi #{operands[0].asmLabel}"
588 when "bz"
589 $asm.puts "beq #{operands[0].asmLabel}"
590 when "bnz"
591 $asm.puts "bne #{operands[0].asmLabel}"
592 when "leai", "leap"
593 operands[0].armEmitLea(operands[1])
594 when "smulli"
595 raise "Wrong number of arguments to smull in #{self.inspect} at #{codeOriginString}" unless operands.length == 4
596 $asm.puts "smull #{operands[2].armOperand}, #{operands[3].armOperand}, #{operands[0].armOperand}, #{operands[1].armOperand}"
81345200
A
597 when "memfence"
598 $asm.puts "dmb sy"
599 when "clrbp"
600 $asm.puts "bic #{operands[2].armOperand}, #{operands[0].armOperand}, #{operands[1].armOperand}"
93a37866
A
601 else
602 lowerDefault
603 end
604 end
605end
606