1 import os
2 import random
3 import subprocess
4 import sys
5
6 AARCH64_AS = "as"
7 AARCH64_OBJDUMP = "objdump"
8 AARCH64_OBJCOPY = "objcopy"
9
10 # These tables are legal immediate logical operands
11 immediates8 \
12 = [0x1, 0x0c, 0x3e, 0x60, 0x7c, 0x80, 0x83,
13 0xe1, 0xbf, 0xef, 0xf3, 0xfe]
14
15 immediates16 \
16 = [0x1, 0x38, 0x7e, 0xff, 0x1fc, 0x1ff, 0x3f0,
17 0x7e0, 0xfc0, 0x1f80, 0x3ff0, 0x7e00, 0x8000,
18 0x81ff, 0xc1ff, 0xc003, 0xc7ff, 0xdfff, 0xe03f,
19 0xe1ff, 0xf801, 0xfc00, 0xfc07, 0xff03, 0xfffe]
20
21 immediates32 \
22 = [0x1, 0x3f, 0x1f0, 0x7e0,
23 0x1c00, 0x3ff0, 0x8000, 0x1e000,
24 0x3e000, 0x78000, 0xe0000, 0x100000,
25 0x1fffe0, 0x3fe000, 0x780000, 0x7ffff8,
26 0xff8000, 0x1800180, 0x1fffc00, 0x3c003c0,
27 0x3ffff00, 0x7c00000, 0x7fffe00, 0xf000f00,
28 0xfffe000, 0x18181818, 0x1ffc0000, 0x1ffffffe,
29 0x3f003f00, 0x3fffe000, 0x60006000, 0x7f807f80,
30 0x7ffffc00, 0x800001ff, 0x803fffff, 0x9f9f9f9f,
31 0xc0000fff, 0xc0c0c0c0, 0xe0000000, 0xe003e003,
32 0xe3ffffff, 0xf0000fff, 0xf0f0f0f0, 0xf80000ff,
33 0xf83ff83f, 0xfc00007f, 0xfc1fffff, 0xfe0001ff,
34 0xfe3fffff, 0xff003fff, 0xff800003, 0xff87ff87,
35 0xffc00fff, 0xffe0000f, 0xffefffef, 0xfff1fff1,
36 0xfff83fff, 0xfffc0fff, 0xfffe0fff, 0xffff3fff,
37 0xffffc007, 0xffffe1ff, 0xfffff80f, 0xfffffe07,
38 0xffffffbf, 0xfffffffd]
39
40 immediates64 \
41 = [0x1, 0x1f80, 0x3fff0, 0x3ffffc,
42 0x3fe0000, 0x1ffc0000, 0xf8000000, 0x3ffffc000,
43 0xffffffe00, 0x3ffffff800, 0xffffc00000, 0x3f000000000,
44 0x7fffffff800, 0x1fe000001fe0, 0x3ffffff80000, 0xc00000000000,
45 0x1ffc000000000, 0x3ffff0003ffff, 0x7ffffffe00000, 0xfffffffffc000,
46 0x1ffffffffffc00, 0x3fffffffffff00, 0x7ffffffffffc00, 0xffffffffff8000,
47 0x1ffffffff800000, 0x3fffffc03fffffc, 0x7fffc0000000000, 0xff80ff80ff80ff8,
48 0x1c00000000000000, 0x1fffffffffff0000, 0x3fffff803fffff80, 0x7fc000007fc00000,
49 0x8000000000000000, 0x803fffff803fffff, 0xc000007fc000007f, 0xe00000000000ffff,
50 0xe3ffffffffffffff, 0xf007f007f007f007, 0xf80003ffffffffff, 0xfc000003fc000003,
51 0xfe000000007fffff, 0xff00000000007fff, 0xff800000000003ff, 0xffc00000000000ff,
52 0xffe00000000003ff, 0xfff0000000003fff, 0xfff80000001fffff, 0xfffc0000fffc0000,
53 0xfffe003fffffffff, 0xffff3fffffffffff, 0xffffc0000007ffff, 0xffffe01fffffe01f,
54 0xfffff800000007ff, 0xfffffc0fffffffff, 0xffffff00003fffff, 0xffffffc0000007ff,
55 0xfffffff0000001ff, 0xfffffffc00003fff, 0xffffffff07ffffff, 0xffffffffe003ffff,
56 0xfffffffffc01ffff, 0xffffffffffc00003, 0xfffffffffffc000f, 0xffffffffffffe07f]
57
58 class Operand(object):
59
60 def generate(self):
61 return self
62
63 class Register(Operand):
64
65 def generate(self):
66 self.number = random.randint(0, 30)
67 if self.number == 18:
68 self.number = 17
69 return self
70
71 def astr(self, prefix):
72 return prefix + str(self.number)
73
74 class FloatRegister(Register):
75
76 def __str__(self):
77 return self.astr("v")
78
79 def generate(self):
80 self.number = random.randint(0, 31)
81 return self
82
83 def nextReg(self):
84 next = FloatRegister()
85 next.number = (self.number + 1) % 32
86 return next
87
88 class LowFloatRegister(Register):
89
90 def __str__(self):
91 return self.astr("v")
92
93 def generate(self):
94 self.number = random.randint(0, 15)
95 return self
96
97 def nextReg(self):
98 next = FloatRegister()
99 next.number = (self.number + 1) % 16
100 return next
101
102 class GeneralRegister(Register):
103
104 def __str__(self):
105 return self.astr("r")
106
107 class GeneralRegisterOrZr(Register):
108
109 def generate(self):
110 self.number = random.randint(0, 31)
111 if self.number == 18:
112 self.number = 16
113 return self
114
115 def astr(self, prefix = ""):
116 if (self.number == 31):
117 return prefix + "zr"
118 else:
119 return prefix + str(self.number)
120
121 def __str__(self):
122 if (self.number == 31):
123 return self.astr()
124 else:
125 return self.astr("r")
126
127 class GeneralRegisterOrSp(Register):
128 def generate(self):
129 self.number = random.randint(0, 31)
130 if self.number == 18:
131 self.number = 15
132 return self
133
134 def astr(self, prefix = ""):
135 if (self.number == 31):
136 return "sp"
137 else:
138 return prefix + str(self.number)
139
140 def __str__(self):
141 if (self.number == 31):
142 return self.astr()
143 else:
144 return self.astr("r")
145
146 class SVEVectorRegister(FloatRegister):
147 def __str__(self):
148 return self.astr("z")
149
150 class SVEPRegister(Register):
151 def __str__(self):
152 return self.astr("p")
153
154 def generate(self):
155 self.number = random.randint(0, 15)
156 return self
157
158 class SVEGoverningPRegister(Register):
159 def __str__(self):
160 return self.astr("p")
161 def generate(self):
162 self.number = random.randint(0, 7)
163 return self
164
165 class RegVariant(object):
166 def __init__(self, low, high):
167 self.number = random.randint(low, high)
168
169 def astr(self):
170 nameMap = {
171 0: ".b",
172 1: ".h",
173 2: ".s",
174 3: ".d",
175 4: ".q"
176 }
177 return nameMap.get(self.number)
178
179 def cstr(self):
180 nameMap = {
181 0: "__ B",
182 1: "__ H",
183 2: "__ S",
184 3: "__ D",
185 4: "__ Q"
186 }
187 return nameMap.get(self.number)
188
189 class FloatZero(Operand):
190
191 def __str__(self):
192 return "0.0"
193
194 def astr(self, ignored):
195 return "#0.0"
196
197 class OperandFactory:
198
199 _modes = {'x' : GeneralRegister,
200 'w' : GeneralRegister,
201 'b' : FloatRegister,
202 'h' : FloatRegister,
203 's' : FloatRegister,
204 'd' : FloatRegister,
205 'z' : FloatZero,
206 'p' : SVEPRegister,
207 'P' : SVEGoverningPRegister,
208 'Z' : SVEVectorRegister}
209
210 @classmethod
211 def create(cls, mode):
212 return OperandFactory._modes[mode]()
213
214 class ShiftKind:
215
216 def generate(self):
217 self.kind = ["LSL", "LSR", "ASR"][random.randint(0,2)]
218 return self
219
220 def cstr(self):
221 return self.kind
222
223 class Instruction(object):
224
225 def __init__(self, name):
226 self._name = name
227 self.isWord = name.endswith("w") | name.endswith("wi")
228 self.asmRegPrefix = ["x", "w"][self.isWord]
229 self.isPostfixException = False
230
231 def aname(self):
232 if self.isPostfixException:
233 return self._name
234 elif (self._name.endswith("wi")):
235 return self._name[:len(self._name)-2]
236 elif (self._name.endswith("i") | self._name.endswith("w")):
237 return self._name[:len(self._name)-1]
238 else:
239 return self._name
240
241 def emit(self) :
242 pass
243
244 def compare(self) :
245 pass
246
247 def generate(self) :
248 return self
249
250 def cstr(self):
251 return '__ %s(' % self.name()
252
253 def astr(self):
254 return '%s\t' % self.aname()
255
256 def name(self):
257 name = self._name
258 if name == "and":
259 name = "andr" # Special case: the name "and" can't be used
260 # in HotSpot, even for a member.
261 return name
262
263 def multipleForms(self):
264 return 0
265
266 class InstructionWithModes(Instruction):
267
268 def __init__(self, name, mode):
269 Instruction.__init__(self, name)
270 self.mode = mode
271 self.isFloat = (mode == 'd') | (mode == 's')
272 if self.isFloat:
273 self.isWord = mode != 'd'
274 self.asmRegPrefix = ["d", "s"][self.isWord]
275 else:
276 self.isWord = mode != 'x'
277 self.asmRegPrefix = ["x", "w"][self.isWord]
278
279 def name(self):
280 return self._name + (self.mode if self.mode != 'x' else '')
281
282 def aname(self):
283 return (self._name+mode if (mode == 'b' or mode == 'h')
284 else self._name)
285
286 class ThreeRegInstruction(Instruction):
287
288 def generate(self):
289 self.reg = [GeneralRegister().generate(), GeneralRegister().generate(),
290 GeneralRegister().generate()]
291 return self
292
293
294 def cstr(self):
295 return (super(ThreeRegInstruction, self).cstr()
296 + ('%s, %s, %s'
297 % (self.reg[0],
298 self.reg[1], self.reg[2])))
299
300 def astr(self):
301 prefix = self.asmRegPrefix
302 return (super(ThreeRegInstruction, self).astr()
303 + ('%s, %s, %s'
304 % (self.reg[0].astr(prefix),
305 self.reg[1].astr(prefix), self.reg[2].astr(prefix))))
306
307 class FourRegInstruction(ThreeRegInstruction):
308
309 def generate(self):
310 self.reg = ThreeRegInstruction.generate(self).reg + [GeneralRegister().generate()]
311 return self
312
313
314 def cstr(self):
315 return (super(FourRegInstruction, self).cstr()
316 + (', %s' % self.reg[3]))
317
318 def astr(self):
319 prefix = self.asmRegPrefix
320 return (super(FourRegInstruction, self).astr()
321 + (', %s' % self.reg[3].astr(prefix)))
322
323 class TwoRegInstruction(Instruction):
324
325 def generate(self):
326 self.reg = [GeneralRegister().generate(), GeneralRegister().generate()]
327 return self
328
329 def cstr(self):
330 return (super(TwoRegInstruction, self).cstr()
331 + '%s, %s' % (self.reg[0],
332 self.reg[1]))
333
334 def astr(self):
335 prefix = self.asmRegPrefix
336 return (super(TwoRegInstruction, self).astr()
337 + ('%s, %s'
338 % (self.reg[0].astr(prefix),
339 self.reg[1].astr(prefix))))
340
341 class TwoRegImmedInstruction(TwoRegInstruction):
342
343 def generate(self):
344 super(TwoRegImmedInstruction, self).generate()
345 self.immed = random.randint(0, 1<<11 -1)
346 return self
347
348 def cstr(self):
349 return (super(TwoRegImmedInstruction, self).cstr()
350 + ', %su' % self.immed)
351
352 def astr(self):
353 return (super(TwoRegImmedInstruction, self).astr()
354 + ', #%s' % self.immed)
355
356 class OneRegOp(Instruction):
357
358 def generate(self):
359 self.reg = GeneralRegister().generate()
360 return self
361
362 def cstr(self):
363 return (super(OneRegOp, self).cstr()
364 + '%s);' % self.reg)
365
366 def astr(self):
367 return (super(OneRegOp, self).astr()
368 + '%s' % self.reg.astr(self.asmRegPrefix))
369
370 class SystemRegOp(Instruction):
371 def __init__(self, args):
372 name, self.system_reg = args
373 Instruction.__init__(self, name)
374 if self.system_reg == 'fpsr':
375 self.op1 = 0b011
376 self.CRn = 0b0100
377 self.CRm = 0b0100
378 self.op2 = 0b001
379 elif self.system_reg == 'dczid_el0':
380 self.op1 = 0b011
381 self.CRn = 0b0000
382 self.CRm = 0b0000
383 self.op2 = 0b111
384 elif self.system_reg == 'ctr_el0':
385 self.op1 = 0b011
386 self.CRn = 0b0000
387 self.CRm = 0b0000
388 self.op2 = 0b001
389 elif self.system_reg == 'nzcv':
390 self.op1 = 0b011
391 self.CRn = 0b0100
392 self.CRm = 0b0010
393 self.op2 = 0b000
394
395 def generate(self):
396 self.reg = [GeneralRegister().generate()]
397 return self
398
399 class SystemOneRegOp(SystemRegOp):
400
401 def cstr(self):
402 return (super(SystemOneRegOp, self).cstr()
403 + '%s' % self.op1
404 + ', %s' % self.CRn
405 + ', %s' % self.CRm
406 + ', %s' % self.op2
407 + ', %s);' % self.reg[0])
408
409 def astr(self):
410 prefix = self.asmRegPrefix
411 return (super(SystemOneRegOp, self).astr()
412 + '%s' % self.system_reg
413 + ', %s' % self.reg[0].astr(prefix))
414
415 class OneRegSystemOp(SystemRegOp):
416
417 def cstr(self):
418 return (super(OneRegSystemOp, self).cstr()
419 + '%s' % self.op1
420 + ', %s' % self.CRn
421 + ', %s' % self.CRm
422 + ', %s' % self.op2
423 + ', %s);' % self.reg[0])
424
425 def astr(self):
426 prefix = self.asmRegPrefix
427 return (super(OneRegSystemOp, self).astr()
428 + '%s' % self.reg[0].astr(prefix)
429 + ', %s' % self.system_reg)
430
431 class PostfixExceptionOneRegOp(OneRegOp):
432
433 def __init__(self, op):
434 OneRegOp.__init__(self, op)
435 self.isPostfixException=True
436
437 class ArithOp(ThreeRegInstruction):
438
439 def generate(self):
440 super(ArithOp, self).generate()
441 self.kind = ShiftKind().generate()
442 self.distance = random.randint(0, (1<<5)-1 if self.isWord else (1<<6)-1)
443 return self
444
445 def cstr(self):
446 return ('%s, Assembler::%s, %s);'
447 % (ThreeRegInstruction.cstr(self),
448 self.kind.cstr(), self.distance))
449
450 def astr(self):
451 return ('%s, %s #%s'
452 % (ThreeRegInstruction.astr(self),
453 self.kind.cstr(),
454 self.distance))
455
456 class AddSubCarryOp(ThreeRegInstruction):
457
458 def cstr(self):
459 return ('%s);'
460 % (ThreeRegInstruction.cstr(self)))
461
462 class AddSubExtendedOp(ThreeRegInstruction):
463
464 uxtb, uxth, uxtw, uxtx, sxtb, sxth, sxtw, sxtx = range(8)
465 optNames = ["uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx"]
466
467 def generate(self):
468 super(AddSubExtendedOp, self).generate()
469 self.amount = random.randint(1, 4)
470 self.option = random.randint(0, 7)
471 return self
472
473 def cstr(self):
474 return (super(AddSubExtendedOp, self).cstr()
475 + (", ext::" + AddSubExtendedOp.optNames[self.option]
476 + ", " + str(self.amount) + ");"))
477
478 def astr(self):
479 return (super(AddSubExtendedOp, self).astr()
480 + (", " + AddSubExtendedOp.optNames[self.option]
481 + " #" + str(self.amount)))
482
483 class AddSubImmOp(TwoRegImmedInstruction):
484
485 def cstr(self):
486 return super(AddSubImmOp, self).cstr() + ");"
487
488 class LogicalImmOp(AddSubImmOp):
489 def generate(self):
490 AddSubImmOp.generate(self)
491 self.immed = \
492 immediates32[random.randint(0, len(immediates32)-1)] \
493 if self.isWord else \
494 immediates64[random.randint(0, len(immediates64)-1)]
495
496 return self
497
498 def astr(self):
499 return (super(TwoRegImmedInstruction, self).astr()
500 + ', #0x%x' % self.immed)
501
502 def cstr(self):
503 return super(AddSubImmOp, self).cstr() + "ll);"
504
505 class SVEBinaryImmOp(Instruction):
506 def __init__(self, name):
507 reg = SVEVectorRegister().generate()
508 self.reg = [reg, reg]
509 self.numRegs = len(self.reg)
510 self._width = RegVariant(0, 3)
511 self._isLogical = False
512 if name in ["and", "eor", "orr"]:
513 self._isLogical = True
514 Instruction.__init__(self, name)
515
516 def generate(self):
517 Instruction.generate(self)
518 self.immed = random.randint(0, (1<<8)-1)
519 if self._isLogical:
520 vectype = self._width.cstr()
521 if vectype == "__ B":
522 self.immed = immediates8[random.randint(0, len(immediates8)-1)]
523 elif vectype == "__ H":
524 self.immed = immediates16[random.randint(0, len(immediates16)-1)]
525 elif vectype == "__ S":
526 self.immed = immediates32[random.randint(0, len(immediates32)-1)]
527 elif vectype == "__ D":
528 self.immed = immediates64[random.randint(0, len(immediates64)-1)]
529 return self
530
531 def cstr(self):
532 formatStr = "%s%s, %s, %su);"
533 return (formatStr
534 % tuple(["__ sve_" + self._name + "("] +
535 [str(self.reg[0]), self._width.cstr(), self.immed]))
536
537 def astr(self):
538 formatStr = "%s%s, %s, #0x%x"
539 Regs = [str(self.reg[i]) + self._width.astr() for i in range(0, self.numRegs)]
540 return (formatStr
541 % tuple([Instruction.astr(self)] + Regs + [self.immed]))
542
543 class SVEComparisonWithZero(Instruction):
544 def __init__(self, arg):
545 Instruction.__init__(self, "fcm")
546 self.condition = arg
547 self.dest = OperandFactory.create('p').generate()
548 self.reg = SVEVectorRegister().generate()
549 self._width = RegVariant(2, 3)
550 self.preg = OperandFactory.create('P').generate()
551
552 def generate(self):
553 return Instruction.generate(self)
554
555 def cstr(self):
556 return ("%s(%s, %s, %s, %s, %s, 0.0);"
557 % ("__ sve_" + self._name, "Assembler::" + self.condition,
558 str(self.dest), self._width.cstr(), str(self.preg), str(self.reg)))
559
560 def astr(self):
561 val = ("%s%s\t%s%s, %s/z, %s%s, #0.0"
562 % (self._name, self.condition.lower(), str(self.dest), self._width.astr(),
563 str(self.preg), str(self.reg), self._width.astr()))
564 return val
565
566 class SVEComparisonWithImm(Instruction):
567 def __init__(self, arg):
568 Instruction.__init__(self, "cmp")
569 self.condition = arg
570 self.dest = OperandFactory.create('p').generate()
571 self.reg = SVEVectorRegister().generate()
572 self._width = RegVariant(0, 3)
573 self.preg = OperandFactory.create('P').generate()
574
575 def generate(self):
576 if self.condition in ['HI', 'HS', 'LO', 'LS']:
577 self.immed = random.randint(0, 127)
578 else:
579 self.immed = random.randint(-16, 15)
580 return Instruction.generate(self)
581
582 def cstr(self):
583 return ("%s(%s, %s, %s, %s, %s, %d);"
584 % ("__ sve_" + self._name, "Assembler::" + self.condition,
585 str(self.dest), self._width.cstr(), str(self.preg), str(self.reg), self.immed))
586
587 def astr(self):
588 val = ("%s%s\t%s%s, %s/z, %s%s, #%d"
589 % (self._name, self.condition.lower(), str(self.dest), self._width.astr(),
590 str(self.preg), str(self.reg), self._width.astr(), self.immed))
591 return val
592
593 class MultiOp():
594
595 def multipleForms(self):
596 return 3
597
598 def forms(self):
599 return ["__ pc()", "back", "forth"]
600
601 def aforms(self):
602 return [".", "back", "forth"]
603
604 class AbsOp(MultiOp, Instruction):
605
606 def cstr(self):
607 return super(AbsOp, self).cstr() + "%s);"
608
609 def astr(self):
610 return Instruction.astr(self) + "%s"
611
612 class RegAndAbsOp(MultiOp, Instruction):
613
614 def multipleForms(self):
615 if self.name() == "adrp":
616 # We can only test one form of adrp because anything other
617 # than "adrp ." requires relocs in the assembler output
618 return 1
619 return 3
620
621 def generate(self):
622 Instruction.generate(self)
623 self.reg = GeneralRegister().generate()
624 return self
625
626 def cstr(self):
627 if self.name() == "adrp":
628 return "__ _adrp(" + "%s, %s);" % (self.reg, "%s")
629 return (super(RegAndAbsOp, self).cstr()
630 + "%s, %s);" % (self.reg, "%s"))
631
632 def astr(self):
633 return (super(RegAndAbsOp, self).astr()
634 + self.reg.astr(self.asmRegPrefix) + ", %s")
635
636 class RegImmAbsOp(RegAndAbsOp):
637
638 def cstr(self):
639 return (Instruction.cstr(self)
640 + "%s, %s, %s);" % (self.reg, self.immed, "%s"))
641
642 def astr(self):
643 return (Instruction.astr(self)
644 + ("%s, #%s, %s"
645 % (self.reg.astr(self.asmRegPrefix), self.immed, "%s")))
646
647 def generate(self):
648 super(RegImmAbsOp, self).generate()
649 self.immed = random.randint(0, 1<<5 -1)
650 return self
651
652 class MoveWideImmOp(RegImmAbsOp):
653
654 def multipleForms(self):
655 return 0
656
657 def cstr(self):
658 return (Instruction.cstr(self)
659 + "%s, %s, %s);" % (self.reg, self.immed, self.shift))
660
661 def astr(self):
662 return (Instruction.astr(self)
663 + ("%s, #%s, lsl %s"
664 % (self.reg.astr(self.asmRegPrefix),
665 self.immed, self.shift)))
666
667 def generate(self):
668 super(RegImmAbsOp, self).generate()
669 self.immed = random.randint(0, 1<<16 -1)
670 if self.isWord:
671 self.shift = random.randint(0, 1) * 16
672 else:
673 self.shift = random.randint(0, 3) * 16
674 return self
675
676 class BitfieldOp(TwoRegInstruction):
677
678 def cstr(self):
679 return (Instruction.cstr(self)
680 + ("%s, %s, %s, %s);"
681 % (self.reg[0], self.reg[1], self.immr, self.imms)))
682
683 def astr(self):
684 return (TwoRegInstruction.astr(self)
685 + (", #%s, #%s"
686 % (self.immr, self.imms)))
687
688 def generate(self):
689 TwoRegInstruction.generate(self)
690 self.immr = random.randint(0, 31)
691 self.imms = random.randint(0, 31)
692 return self
693
694 class ExtractOp(ThreeRegInstruction):
695
696 def generate(self):
697 super(ExtractOp, self).generate()
698 self.lsb = random.randint(0, (1<<5)-1 if self.isWord else (1<<6)-1)
699 return self
700
701 def cstr(self):
702 return (ThreeRegInstruction.cstr(self)
703 + (", %s);" % self.lsb))
704
705 def astr(self):
706 return (ThreeRegInstruction.astr(self)
707 + (", #%s" % self.lsb))
708
709 class CondBranchOp(MultiOp, Instruction):
710
711 def cstr(self):
712 return "__ br(Assembler::" + self.name() + ", %s);"
713
714 def astr(self):
715 return "b." + self.name() + "\t%s"
716
717 class ImmOp(Instruction):
718
719 def cstr(self):
720 return "%s%s);" % (Instruction.cstr(self), self.immed)
721
722 def astr(self):
723 return Instruction.astr(self) + "#" + str(self.immed)
724
725 def generate(self):
726 self.immed = random.randint(0, 1<<16 -1)
727 return self
728
729 class Op(Instruction):
730
731 def cstr(self):
732 return Instruction.cstr(self) + ");"
733 def astr(self):
734 return self.aname();
735
736
737 class PostfixExceptionOp(Op):
738
739 def __init__(self, op):
740 Op.__init__(self, op)
741 self.isPostfixException=True
742
743 class SystemOp(Instruction):
744
745 def __init__(self, op):
746 Instruction.__init__(self, op[0])
747 self.barriers = op[1]
748
749 def generate(self):
750 Instruction.generate(self)
751 self.barrier \
752 = self.barriers[random.randint(0, len(self.barriers)-1)]
753 return self
754
755 def cstr(self):
756 return Instruction.cstr(self) + "Assembler::" + self.barrier + ");"
757
758 def astr(self):
759 return Instruction.astr(self) + self.barrier
760
761 conditionCodes = ["EQ", "NE", "HS", "CS", "LO", "CC", "MI", "PL", "VS", \
762 "VC", "HI", "LS", "GE", "LT", "GT", "LE", "AL", "NV"]
763
764 class ConditionalCompareOp(TwoRegImmedInstruction):
765
766 def generate(self):
767 TwoRegImmedInstruction.generate(self)
768 self.cond = random.randint(0, 15)
769 self.immed = random.randint(0, 15)
770 return self
771
772 def cstr(self):
773 return (super(ConditionalCompareOp, self).cstr() + ", "
774 + "Assembler::" + conditionCodes[self.cond] + ");")
775
776 def astr(self):
777 return (super(ConditionalCompareOp, self).astr() +
778 ", " + conditionCodes[self.cond])
779
780 class ConditionalCompareImmedOp(Instruction):
781
782 def generate(self):
783 self.reg = GeneralRegister().generate()
784 self.cond = random.randint(0, 15)
785 self.immed2 = random.randint(0, 15)
786 self.immed = random.randint(0, 31)
787 return self
788
789 def cstr(self):
790 return (Instruction.cstr(self) + str(self.reg) + ", "
791 + str(self.immed) + ", "
792 + str(self.immed2) + ", "
793 + "Assembler::" + conditionCodes[self.cond] + ");")
794
795 def astr(self):
796 return (Instruction.astr(self)
797 + self.reg.astr(self.asmRegPrefix)
798 + ", #" + str(self.immed)
799 + ", #" + str(self.immed2)
800 + ", " + conditionCodes[self.cond])
801
802 class TwoRegOp(TwoRegInstruction):
803
804 def cstr(self):
805 return TwoRegInstruction.cstr(self) + ");"
806
807 class ThreeRegOp(ThreeRegInstruction):
808
809 def cstr(self):
810 return ThreeRegInstruction.cstr(self) + ");"
811
812 class FourRegMulOp(FourRegInstruction):
813
814 def cstr(self):
815 return FourRegInstruction.cstr(self) + ");"
816
817 def astr(self):
818 isMaddsub = self.name().startswith("madd") | self.name().startswith("msub")
819 midPrefix = self.asmRegPrefix if isMaddsub else "w"
820 return (Instruction.astr(self)
821 + self.reg[0].astr(self.asmRegPrefix)
822 + ", " + self.reg[1].astr(midPrefix)
823 + ", " + self.reg[2].astr(midPrefix)
824 + ", " + self.reg[3].astr(self.asmRegPrefix))
825
826 class ConditionalSelectOp(ThreeRegInstruction):
827
828 def generate(self):
829 ThreeRegInstruction.generate(self)
830 self.cond = random.randint(0, 15)
831 return self
832
833 def cstr(self):
834 return (ThreeRegInstruction.cstr(self) + ", "
835 + "Assembler::" + conditionCodes[self.cond] + ");")
836
837 def astr(self):
838 return (ThreeRegInstruction.astr(self)
839 + ", " + conditionCodes[self.cond])
840
841 class LoadStoreExclusiveOp(InstructionWithModes):
842
843 def __init__(self, op): # op is a tuple of ["name", "mode", registers]
844 InstructionWithModes.__init__(self, op[0], op[1])
845 self.num_registers = op[2]
846
847 def astr(self):
848 result = self.aname() + '\t'
849 regs = list(self.regs)
850 index = regs.pop() # The last reg is the index register
851 prefix = ('x' if (self.mode == 'x')
852 & ((self.name().startswith("ld"))
853 | (self.name().startswith("stlr"))) # Ewww :-(
854 else 'w')
855 result = result + regs.pop(0).astr(prefix) + ", "
856 for s in regs:
857 result = result + s.astr(self.asmRegPrefix) + ", "
858 result = result + "[" + index.astr("x") + "]"
859 return result
860
861 def cstr(self):
862 result = InstructionWithModes.cstr(self)
863 regs = list(self.regs)
864 index = regs.pop() # The last reg is the index register
865 for s in regs:
866 result = result + str(s) + ", "
867 result = result + str(index) + ");"
868 return result
869
870 def appendUniqueReg(self):
871 result = 0
872 while result == 0:
873 newReg = GeneralRegister().generate()
874 result = 1
875 for i in self.regs:
876 result = result and (i.number != newReg.number)
877 self.regs.append(newReg)
878
879 def generate(self):
880 self.regs = []
881 for i in range(self.num_registers):
882 self.appendUniqueReg()
883 return self
884
885 def name(self):
886 if self.mode == 'x':
887 return self._name
888 else:
889 return self._name + self.mode
890
891 def aname(self):
892 if (self.mode == 'b') | (self.mode == 'h'):
893 return self._name + self.mode
894 else:
895 return self._name
896
897 class Address(object):
898
899 base_plus_unscaled_offset, pre, post, base_plus_reg, \
900 base_plus_scaled_offset, pcrel, post_reg, base_only = range(8)
901 kinds = ["base_plus_unscaled_offset", "pre", "post", "base_plus_reg",
902 "base_plus_scaled_offset", "pcrel", "post_reg", "base_only"]
903 extend_kinds = ["uxtw", "lsl", "sxtw", "sxtx"]
904
905 @classmethod
906 def kindToStr(cls, i):
907 return cls.kinds[i]
908
909 def generate(self, kind, shift_distance):
910 self.kind = kind
911 self.base = GeneralRegister().generate()
912 self.index = GeneralRegister().generate()
913 self.offset = {
914 Address.base_plus_unscaled_offset: random.randint(-1<<8, 1<<8-1) | 1,
915 Address.pre: random.randint(-1<<8, 1<<8-1),
916 Address.post: random.randint(-1<<8, 1<<8-1),
917 Address.pcrel: random.randint(0, 2),
918 Address.base_plus_reg: 0,
919 Address.base_plus_scaled_offset: (random.randint(0, 1<<11-1) | (3 << 9))*8,
920 Address.post_reg: 0,
921 Address.base_only: 0} [kind]
922 self.offset >>= (3 - shift_distance)
923 self.extend_kind = Address.extend_kinds[random.randint(0, 3)]
924 self.shift_distance = random.randint(0, 1) * shift_distance
925 return self
926
927 def __str__(self):
928 result = {
929 Address.base_plus_unscaled_offset: "Address(%s, %s)" \
930 % (str(self.base), self.offset),
931 Address.pre: "Address(__ pre(%s, %s))" % (str(self.base), self.offset),
932 Address.post: "Address(__ post(%s, %s))" % (str(self.base), self.offset),
933 Address.post_reg: "Address(__ post(%s, %s))" % (str(self.base), self.index),
934 Address.base_only: "Address(%s)" % (str(self.base)),
935 Address.pcrel: "",
936 Address.base_plus_reg: "Address(%s, %s, Address::%s(%s))" \
937 % (self.base, self.index, self.extend_kind, self.shift_distance),
938 Address.base_plus_scaled_offset:
939 "Address(%s, %s)" % (self.base, self.offset) } [self.kind]
940 if (self.kind == Address.pcrel):
941 result = ["__ pc()", "back", "forth"][self.offset]
942 return result
943
944 def astr(self, prefix):
945 extend_prefix = prefix
946 if self.kind == Address.base_plus_reg:
947 if self.extend_kind.endswith("w"):
948 extend_prefix = "w"
949 result = {
950 Address.base_plus_unscaled_offset: "[%s, %s]" \
951 % (self.base.astr(prefix), self.offset),
952 Address.pre: "[%s, %s]!" % (self.base.astr(prefix), self.offset),
953 Address.post: "[%s], %s" % (self.base.astr(prefix), self.offset),
954 Address.post_reg: "[%s], %s" % (self.base.astr(prefix), self.index.astr(prefix)),
955 Address.base_only: "[%s]" % (self.base.astr(prefix)),
956 Address.pcrel: "",
957 Address.base_plus_reg: "[%s, %s, %s #%s]" \
958 % (self.base.astr(prefix), self.index.astr(extend_prefix),
959 self.extend_kind, self.shift_distance),
960 Address.base_plus_scaled_offset: \
961 "[%s, %s]" \
962 % (self.base.astr(prefix), self.offset)
963 } [self.kind]
964 if (self.kind == Address.pcrel):
965 result = [".", "back", "forth"][self.offset]
966 return result
967
968 class LoadStoreOp(InstructionWithModes):
969
970 def __init__(self, args):
971 name, self.asmname, self.kind, mode = args
972 InstructionWithModes.__init__(self, name, mode)
973
974 def generate(self):
975
976 # This is something of a kludge, but the offset needs to be
977 # scaled by the memory datamode somehow.
978 shift = 3
979 if (self.mode == 'b') | (self.asmname.endswith("b")):
980 shift = 0
981 elif (self.mode == 'h') | (self.asmname.endswith("h")):
982 shift = 1
983 elif (self.mode == 'w') | (self.asmname.endswith("w")) \
984 | (self.mode == 's') :
985 shift = 2
986
987 self.adr = Address().generate(self.kind, shift)
988
989 isFloat = (self.mode == 'd') | (self.mode == 's')
990
991 regMode = FloatRegister if isFloat else GeneralRegister
992 self.reg = regMode().generate()
993 kindStr = Address.kindToStr(self.kind);
994 if (not isFloat) and (kindStr is "pre" or kindStr is "post"):
995 (self.reg.number, self.adr.base.number) = random.sample(list(set(range(31)) - set([18])), 2)
996 return self
997
998 def cstr(self):
999 if not(self._name.startswith("prfm")):
1000 return "%s%s, %s);" % (Instruction.cstr(self), str(self.reg), str(self.adr))
1001 else: # No target register for a prefetch
1002 return "%s%s);" % (Instruction.cstr(self), str(self.adr))
1003
1004 def astr(self):
1005 if not(self._name.startswith("prfm")):
1006 return "%s\t%s, %s" % (self.aname(), self.reg.astr(self.asmRegPrefix),
1007 self.adr.astr("x"))
1008 else: # No target register for a prefetch
1009 return "%s %s" % (self.aname(),
1010 self.adr.astr("x"))
1011
1012 def aname(self):
1013 result = self.asmname
1014 # if self.kind == Address.base_plus_unscaled_offset:
1015 # result = result.replace("ld", "ldu", 1)
1016 # result = result.replace("st", "stu", 1)
1017 return result
1018
1019 class LoadStorePairOp(InstructionWithModes):
1020
1021 numRegs = 2
1022
1023 def __init__(self, args):
1024 name, self.asmname, self.kind, mode = args
1025 InstructionWithModes.__init__(self, name, mode)
1026 self.offset = random.randint(-1<<4, 1<<4-1) << 4
1027
1028 def generate(self):
1029 self.reg = [OperandFactory.create(self.mode).generate()
1030 for i in range(self.numRegs)]
1031 self.base = OperandFactory.create('x').generate()
1032 kindStr = Address.kindToStr(self.kind);
1033 if kindStr is "pre" or kindStr is "post":
1034 if self._name.startswith("ld"):
1035 (self.reg[0].number, self.reg[1].number, self.base.number) = random.sample(list(set(range(31)) - set([18])), 3)
1036 if self._name.startswith("st"):
1037 self.base.number = random.choice(list(set(range(31)) - set([self.reg[0].number, self.reg[1].number, 18])))
1038 elif self._name.startswith("ld"):
1039 (self.reg[0].number, self.reg[1].number) = random.sample(list(set(range(31)) - set([18])), 2)
1040 return self
1041
1042 def astr(self):
1043 address = ["[%s, #%s]", "[%s, #%s]!", "[%s], #%s"][self.kind]
1044 address = address % (self.base.astr('x'), self.offset)
1045 result = "%s\t%s, %s, %s" \
1046 % (self.asmname,
1047 self.reg[0].astr(self.asmRegPrefix),
1048 self.reg[1].astr(self.asmRegPrefix), address)
1049 return result
1050
1051 def cstr(self):
1052 address = {
1053 Address.base_plus_unscaled_offset: "Address(%s, %s)" \
1054 % (str(self.base), self.offset),
1055 Address.pre: "Address(__ pre(%s, %s))" % (str(self.base), self.offset),
1056 Address.post: "Address(__ post(%s, %s))" % (str(self.base), self.offset),
1057 } [self.kind]
1058 result = "__ %s(%s, %s, %s);" \
1059 % (self.name(), self.reg[0], self.reg[1], address)
1060 return result
1061
1062 class FloatInstruction(Instruction):
1063
1064 def aname(self):
1065 if (self._name in ["fcvtsh", "fcvths"]):
1066 return self._name[:len(self._name)-2]
1067 elif (self._name.endswith("h") | self._name.endswith("s") | self._name.endswith("d")):
1068 return self._name[:len(self._name)-1]
1069 else:
1070 return self._name
1071
1072 def __init__(self, args):
1073 name, self.modes = args
1074 Instruction.__init__(self, name)
1075
1076 def generate(self):
1077 self.reg = [OperandFactory.create(self.modes[i]).generate()
1078 for i in range(self.numRegs)]
1079 return self
1080
1081 def cstr(self):
1082 formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)] + [");"])
1083 return (formatStr
1084 % tuple([Instruction.cstr(self)] +
1085 [str(self.reg[i]) for i in range(self.numRegs)])) # Yowza
1086
1087 def astr(self):
1088 formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)])
1089 return (formatStr
1090 % tuple([Instruction.astr(self)] +
1091 [(self.reg[i].astr(self.modes[i])) for i in range(self.numRegs)]))
1092
1093 class SVEVectorOp(Instruction):
1094 def __init__(self, args):
1095 name = args[0]
1096 regTypes = args[1]
1097 regs = []
1098 for c in regTypes:
1099 regs.append(OperandFactory.create(c).generate())
1100 self.reg = regs
1101 self.numRegs = len(regs)
1102 if regTypes[0] != "p" and regTypes[1] == 'P':
1103 self._isPredicated = True
1104 assert len(args) > 2, "Must specify predicate type"
1105 for arg in args[2:]:
1106 if arg == 'm':
1107 self._merge = "/m"
1108 elif arg == 'z':
1109 self._merge = "/z"
1110 else:
1111 assert arg == "dn", "Unknown predicate type"
1112 else:
1113 self._isPredicated = False
1114 self._merge = ""
1115
1116 self._bitwiseop = False
1117 if name[0] == 'f':
1118 self._width = RegVariant(2, 3)
1119 elif not self._isPredicated and (name in ["and", "eor", "orr", "bic", "eor3"]):
1120 self._width = RegVariant(3, 3)
1121 self._bitwiseop = True
1122 elif name == "revb":
1123 self._width = RegVariant(1, 3)
1124 else:
1125 self._width = RegVariant(0, 3)
1126
1127 self._dnm = None
1128 if len(args) > 2:
1129 for arg in args[2:]:
1130 if arg == "dn":
1131 self._dnm = arg
1132
1133 Instruction.__init__(self, name)
1134
1135 def cstr(self):
1136 formatStr = "%s%s" + ''.join([", %s" for i in range(0, self.numRegs)] + [");"])
1137 if self._bitwiseop:
1138 width = []
1139 formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)] + [");"])
1140 else:
1141 width = [self._width.cstr()]
1142 return (formatStr
1143 % tuple(["__ sve_" + self._name + "("] +
1144 [str(self.reg[0])] +
1145 width +
1146 [str(self.reg[i]) for i in range(1, self.numRegs)]))
1147 def astr(self):
1148 firstArg = 0 if self._name == "eor3" else 1
1149 formatStr = "%s%s" + ''.join([", %s" for i in range(firstArg, self.numRegs)])
1150 if self._dnm == 'dn':
1151 formatStr += ", %s"
1152 dnReg = [str(self.reg[0]) + self._width.astr()]
1153 else:
1154 dnReg = []
1155
1156 if self._isPredicated:
1157 restRegs = [str(self.reg[1]) + self._merge] + dnReg + [str(self.reg[i]) + self._width.astr() for i in range(2, self.numRegs)]
1158 else:
1159 restRegs = dnReg + [str(self.reg[i]) + self._width.astr() for i in range(firstArg, self.numRegs)]
1160 return (formatStr
1161 % tuple([Instruction.astr(self)] +
1162 [str(self.reg[0]) + self._width.astr()] +
1163 restRegs))
1164 def generate(self):
1165 return self
1166
1167 class SVEReductionOp(Instruction):
1168 def __init__(self, args):
1169 name = args[0]
1170 lowRegType = args[1]
1171 self.reg = []
1172 Instruction.__init__(self, name)
1173 self.reg.append(OperandFactory.create('s').generate())
1174 self.reg.append(OperandFactory.create('P').generate())
1175 self.reg.append(OperandFactory.create('Z').generate())
1176 self._width = RegVariant(lowRegType, 3)
1177 def cstr(self):
1178 return "__ sve_%s(%s, %s, %s, %s);" % (self.name(),
1179 str(self.reg[0]),
1180 self._width.cstr(),
1181 str(self.reg[1]),
1182 str(self.reg[2]))
1183 def astr(self):
1184 if self.name() == "uaddv":
1185 dstRegName = "d" + str(self.reg[0].number)
1186 else:
1187 dstRegName = self._width.astr()[1] + str(self.reg[0].number)
1188 formatStr = "%s %s, %s, %s"
1189 if self.name() == "fadda":
1190 formatStr += ", %s"
1191 moreReg = [dstRegName]
1192 else:
1193 moreReg = []
1194 return formatStr % tuple([self.name()] +
1195 [dstRegName] +
1196 [str(self.reg[1])] +
1197 moreReg +
1198 [str(self.reg[2]) + self._width.astr()])
1199
1200 class LdStNEONOp(Instruction):
1201 def __init__(self, args):
1202 self._name, self.regnum, self.arrangement, self.addresskind = args
1203
1204 def generate(self):
1205 self.address = Address().generate(self.addresskind, 0)
1206 self._firstSIMDreg = FloatRegister().generate()
1207 if (self.addresskind == Address.post):
1208 if (self._name in ["ld1r", "ld2r", "ld3r", "ld4r"]):
1209 elem_size = {"8B" : 1, "16B" : 1, "4H" : 2, "8H" : 2, "2S" : 4, "4S" : 4, "1D" : 8, "2D" : 8} [self.arrangement]
1210 self.address.offset = self.regnum * elem_size
1211 else:
1212 if (self.arrangement in ["8B", "4H", "2S", "1D"]):
1213 self.address.offset = self.regnum * 8
1214 else:
1215 self.address.offset = self.regnum * 16
1216 return self
1217
1218 def cstr(self):
1219 buf = super(LdStNEONOp, self).cstr() + str(self._firstSIMDreg)
1220 current = self._firstSIMDreg
1221 for cnt in range(1, self.regnum):
1222 buf = '%s, %s' % (buf, current.nextReg())
1223 current = current.nextReg()
1224 return '%s, __ T%s, %s);' % (buf, self.arrangement, str(self.address))
1225
1226 def astr(self):
1227 buf = '%s\t{%s.%s' % (self._name, self._firstSIMDreg, self.arrangement)
1228 current = self._firstSIMDreg
1229 for cnt in range(1, self.regnum):
1230 buf = '%s, %s.%s' % (buf, current.nextReg(), self.arrangement)
1231 current = current.nextReg()
1232 return '%s}, %s' % (buf, self.address.astr("x"))
1233
1234 def aname(self):
1235 return self._name
1236
1237 class NEONReduceInstruction(Instruction):
1238 def __init__(self, args):
1239 self._name, self.insname, self.arrangement = args
1240
1241 def generate(self):
1242 current = FloatRegister().generate()
1243 self.dstSIMDreg = current
1244 self.srcSIMDreg = current.nextReg()
1245 return self
1246
1247 def cstr(self):
1248 buf = Instruction.cstr(self) + str(self.dstSIMDreg)
1249 if self._name == "fmaxp" or self._name == "fminp":
1250 buf = '%s, %s, __ %s);' % (buf, self.srcSIMDreg, self.arrangement[1:])
1251 else:
1252 buf = '%s, __ T%s, %s);' % (buf, self.arrangement, self.srcSIMDreg)
1253 return buf
1254
1255 def astr(self):
1256 buf = '%s\t%s' % (self.insname, self.dstSIMDreg.astr(self.arrangement[-1].lower()))
1257 buf = '%s, %s.%s' % (buf, self.srcSIMDreg, self.arrangement)
1258 return buf
1259
1260 def aname(self):
1261 return self._name
1262
1263 class CommonNEONInstruction(Instruction):
1264 def __init__(self, args):
1265 self._name, self.insname, self.arrangement = args
1266
1267 def generate(self):
1268 self._firstSIMDreg = FloatRegister().generate()
1269 return self
1270
1271 def cstr(self):
1272 buf = Instruction.cstr(self) + str(self._firstSIMDreg)
1273 buf = '%s, __ T%s' % (buf, self.arrangement)
1274 current = self._firstSIMDreg
1275 for cnt in range(1, self.numRegs):
1276 buf = '%s, %s' % (buf, current.nextReg())
1277 current = current.nextReg()
1278 return '%s);' % (buf)
1279
1280 def astr(self):
1281 buf = '%s\t%s.%s' % (self.insname, self._firstSIMDreg, self.arrangement)
1282 current = self._firstSIMDreg
1283 for cnt in range(1, self.numRegs):
1284 buf = '%s, %s.%s' % (buf, current.nextReg(), self.arrangement)
1285 current = current.nextReg()
1286 return buf
1287
1288 def aname(self):
1289 return self._name
1290
1291 class VectorScalarNEONInstruction(Instruction):
1292 def __init__(self, args):
1293 self._name, self.insname, self.arrangement = args
1294
1295 def generate(self):
1296 vectorLength = {"8B" : 8, "16B" : 16, "4H" : 4, "8H" : 8, "2S" : 2, "4S" : 4, "1D" : 1, "2D" : 2} [self.arrangement]
1297 self.elemIndex = random.randrange(0, vectorLength)
1298 self.elemSizeSpecifier = self.arrangement[len(self.arrangement) - 1:]
1299 self._firstSIMDreg = LowFloatRegister().generate()
1300 self.numRegs = 3
1301 return self
1302
1303 def cstr(self):
1304 buf = Instruction.cstr(self) + str(self._firstSIMDreg)
1305 buf = '%s, __ T%s' % (buf, self.arrangement)
1306 current = self._firstSIMDreg
1307 for cnt in range(1, self.numRegs - 1):
1308 buf = '%s, %s' % (buf, current.nextReg())
1309 current = current.nextReg()
1310 buf = '%s, %s, %d' % (buf, current.nextReg(), self.elemIndex)
1311 return '%s);' % (buf)
1312
1313 def astr(self):
1314 buf = '%s\t%s.%s' % (self.insname, self._firstSIMDreg, self.arrangement)
1315 current = self._firstSIMDreg
1316 for cnt in range(1, self.numRegs - 1):
1317 buf = '%s, %s.%s' % (buf, current.nextReg(), self.arrangement)
1318 current = current.nextReg()
1319 buf = '%s, %s.%s[%d]' % (buf, current.nextReg(), self.elemSizeSpecifier, self.elemIndex)
1320 return buf
1321
1322 def aname(self):
1323 return self._name
1324
1325 class WideningNEONInstruction(Instruction):
1326 def __init__(self, args):
1327 self._name, self.insname, self.widerArrangement, self.narrowerArrangement = args
1328
1329 def generate(self):
1330 self._firstSIMDreg = FloatRegister().generate()
1331 return self
1332
1333 def cstr(self):
1334 buf = Instruction.cstr(self) + str(self._firstSIMDreg)
1335 current = self._firstSIMDreg
1336 for cnt in range(1, self.numWiderRegs):
1337 buf = '%s, %s' % (buf, current.nextReg())
1338 current = current.nextReg()
1339 buf = '%s, __ T%s' % (buf, self.widerArrangement)
1340 for cnt in range(0, self.numNarrowerRegs):
1341 buf = '%s, %s' % (buf, current.nextReg())
1342 current = current.nextReg()
1343 buf = '%s, __ T%s' % (buf, self.narrowerArrangement)
1344 return '%s);' % (buf)
1345
1346 def astr(self):
1347 buf = '%s\t%s.%s' % (self.insname, self._firstSIMDreg, self.widerArrangement)
1348 current = self._firstSIMDreg
1349 for cnt in range(1, self.numWiderRegs):
1350 buf = '%s, %s.%s' % (buf, current.nextReg(), self.widerArrangement)
1351 current = current.nextReg()
1352 for cnt in range(0, self.numNarrowerRegs):
1353 buf = '%s, %s.%s' % (buf, current.nextReg(), self.narrowerArrangement)
1354 current = current.nextReg()
1355 return buf
1356
1357 def aname(self):
1358 return self._name
1359
1360 class SHA512SIMDOp(Instruction):
1361
1362 def generate(self):
1363 if (self._name == 'sha512su0'):
1364 self.reg = [FloatRegister().generate(), FloatRegister().generate()]
1365 else:
1366 self.reg = [FloatRegister().generate(), FloatRegister().generate(),
1367 FloatRegister().generate()]
1368 return self
1369
1370 def cstr(self):
1371 if (self._name == 'sha512su0'):
1372 return (super(SHA512SIMDOp, self).cstr()
1373 + ('%s, __ T2D, %s);' % (self.reg[0], self.reg[1])))
1374 else:
1375 return (super(SHA512SIMDOp, self).cstr()
1376 + ('%s, __ T2D, %s, %s);' % (self.reg[0], self.reg[1], self.reg[2])))
1377
1378 def astr(self):
1379 if (self._name == 'sha512su0'):
1380 return (super(SHA512SIMDOp, self).astr()
1381 + ('\t%s.2D, %s.2D' % (self.reg[0].astr("v"), self.reg[1].astr("v"))))
1382 elif (self._name == 'sha512su1'):
1383 return (super(SHA512SIMDOp, self).astr()
1384 + ('\t%s.2D, %s.2D, %s.2D' % (self.reg[0].astr("v"),
1385 self.reg[1].astr("v"), self.reg[2].astr("v"))))
1386 else:
1387 return (super(SHA512SIMDOp, self).astr()
1388 + ('\t%s, %s, %s.2D' % (self.reg[0].astr("q"),
1389 self.reg[1].astr("q"), self.reg[2].astr("v"))))
1390
1391 class SHA3SIMDOp(Instruction):
1392
1393 def generate(self):
1394 if ((self._name == 'eor3') or (self._name == 'bcax')):
1395 self.reg = [FloatRegister().generate(), FloatRegister().generate(),
1396 FloatRegister().generate(), FloatRegister().generate()]
1397 else:
1398 self.reg = [FloatRegister().generate(), FloatRegister().generate(),
1399 FloatRegister().generate()]
1400 if (self._name == 'xar'):
1401 self.imm6 = random.randint(0, 63)
1402 return self
1403
1404 def cstr(self):
1405 if ((self._name == 'eor3') or (self._name == 'bcax')):
1406 return (super(SHA3SIMDOp, self).cstr()
1407 + ('%s, __ T16B, %s, %s, %s);' % (self.reg[0], self.reg[1], self.reg[2], self.reg[3])))
1408 elif (self._name == 'rax1'):
1409 return (super(SHA3SIMDOp, self).cstr()
1410 + ('%s, __ T2D, %s, %s);' % (self.reg[0], self.reg[1], self.reg[2])))
1411 else:
1412 return (super(SHA3SIMDOp, self).cstr()
1413 + ('%s, __ T2D, %s, %s, %s);' % (self.reg[0], self.reg[1], self.reg[2], self.imm6)))
1414
1415 def astr(self):
1416 if ((self._name == 'eor3') or (self._name == 'bcax')):
1417 return (super(SHA3SIMDOp, self).astr()
1418 + ('\t%s.16B, %s.16B, %s.16B, %s.16B' % (self.reg[0].astr("v"), self.reg[1].astr("v"),
1419 self.reg[2].astr("v"), self.reg[3].astr("v"))))
1420 elif (self._name == 'rax1'):
1421 return (super(SHA3SIMDOp, self).astr()
1422 + ('\t%s.2D, %s.2D, %s.2D') % (self.reg[0].astr("v"), self.reg[1].astr("v"),
1423 self.reg[2].astr("v")))
1424 else:
1425 return (super(SHA3SIMDOp, self).astr()
1426 + ('\t%s.2D, %s.2D, %s.2D, #%s') % (self.reg[0].astr("v"), self.reg[1].astr("v"),
1427 self.reg[2].astr("v"), self.imm6))
1428
1429 class LSEOp(Instruction):
1430 def __init__(self, args):
1431 self._name, self.asmname, self.size, self.suffix = args
1432
1433 def generate(self):
1434 self._name = "%s%s" % (self._name, self.suffix)
1435 self.asmname = "%s%s" % (self.asmname, self.suffix)
1436 self.srcReg = GeneralRegisterOrZr().generate()
1437 self.tgtReg = GeneralRegisterOrZr().generate()
1438 self.adrReg = GeneralRegisterOrSp().generate()
1439
1440 return self
1441
1442 def cstr(self):
1443 sizeSpec = {"x" : "Assembler::xword", "w" : "Assembler::word"} [self.size]
1444 return super(LSEOp, self).cstr() + "%s, %s, %s, %s);" % (sizeSpec, self.srcReg, self.tgtReg, self.adrReg)
1445
1446 def astr(self):
1447 return "%s\t%s, %s, [%s]" % (self.asmname, self.srcReg.astr(self.size), self.tgtReg.astr(self.size), self.adrReg.astr("x"))
1448
1449 def aname(self):
1450 return self.asmname
1451
1452 class TwoRegFloatOp(FloatInstruction):
1453 numRegs = 2
1454
1455 class ThreeRegFloatOp(TwoRegFloatOp):
1456 numRegs = 3
1457
1458 class FourRegFloatOp(TwoRegFloatOp):
1459 numRegs = 4
1460
1461 class FloatConvertOp(TwoRegFloatOp):
1462
1463 def __init__(self, args):
1464 self._cname, self._aname, modes = args
1465 TwoRegFloatOp.__init__(self, [self._cname, modes])
1466
1467 def aname(self):
1468 return self._aname
1469
1470 def cname(self):
1471 return self._cname
1472
1473 class TwoRegNEONOp(CommonNEONInstruction):
1474 numRegs = 2
1475
1476 class ThreeRegNEONOp(TwoRegNEONOp):
1477 numRegs = 3
1478
1479 class AddWideNEONOp(WideningNEONInstruction):
1480 numWiderRegs = 2
1481 numNarrowerRegs = 1
1482
1483 class NEONFloatCompareWithZero(TwoRegNEONOp):
1484 def __init__(self, args):
1485 self._name = 'fcm'
1486 self.arrangement, self.condition = args
1487 self.insname = self._name + (self.condition).lower()
1488
1489 def cstr(self):
1490 return ("%s(%s, %s, %s, %s);"
1491 % ("__ " + self._name,
1492 "Assembler::" + self.condition,
1493 self._firstSIMDreg,
1494 "__ T" + self.arrangement,
1495 self._firstSIMDreg.nextReg()))
1496
1497 def astr(self):
1498 return ("%s\t%s.%s, %s.%s, #0.0"
1499 % (self.insname,
1500 self._firstSIMDreg,
1501 self.arrangement,
1502 self._firstSIMDreg.nextReg(),
1503 self.arrangement))
1504
1505 class NEONVectorCompare(ThreeRegNEONOp):
1506 def __init__(self, args):
1507 self._name, self.arrangement, self.condition = args
1508 self.insname = self._name + (self.condition).lower()
1509
1510 def cstr(self):
1511 return ("%s(%s, %s, %s, %s, %s);"
1512 % ("__ " + self._name,
1513 "Assembler::" + self.condition,
1514 self._firstSIMDreg,
1515 "__ T" + self.arrangement,
1516 self._firstSIMDreg.nextReg(),
1517 self._firstSIMDreg.nextReg().nextReg()))
1518
1519 def astr(self):
1520 return ("%s\t%s.%s, %s.%s, %s.%s"
1521 % (self.insname,
1522 self._firstSIMDreg,
1523 self.arrangement,
1524 self._firstSIMDreg.nextReg(),
1525 self.arrangement,
1526 self._firstSIMDreg.nextReg().nextReg(),
1527 self.arrangement))
1528
1529 class SpecialCases(Instruction):
1530 def __init__(self, data):
1531 self._name = data[0]
1532 self._cstr = data[1]
1533 self._astr = data[2]
1534
1535 def cstr(self):
1536 return self._cstr
1537
1538 def astr(self):
1539 return self._astr
1540
1541 def generate(kind, names):
1542 outfile.write("# " + kind.__name__ + "\n");
1543 print "\n// " + kind.__name__
1544 for name in names:
1545 for i in range(1):
1546 op = kind(name).generate()
1547 if op.multipleForms():
1548 forms = op.forms()
1549 aforms = op.aforms()
1550 for i in range(op.multipleForms()):
1551 cstr = op.cstr() % forms[i]
1552 astr = op.astr() % aforms[i]
1553 print " %-50s //\t%s" % (cstr, astr)
1554 outfile.write("\t" + astr + "\n")
1555 else:
1556 print " %-50s //\t%s" % (op.cstr(), op.astr())
1557 outfile.write("\t" + op.astr() + "\n")
1558
1559 outfile = open("aarch64ops.s", "w")
1560
1561 # To minimize the changes of assembler test code
1562 random.seed(0)
1563
1564 print "// BEGIN Generated code -- do not edit"
1565 print "// Generated by aarch64-asmtest.py"
1566
1567 print " Label back, forth;"
1568 print " __ bind(back);"
1569
1570 outfile.write("back:\n")
1571
1572 generate (ArithOp,
1573 [ "add", "sub", "adds", "subs",
1574 "addw", "subw", "addsw", "subsw",
1575 "and", "orr", "eor", "ands",
1576 "andw", "orrw", "eorw", "andsw",
1577 "bic", "orn", "eon", "bics",
1578 "bicw", "ornw", "eonw", "bicsw" ])
1579
1580 generate (AddSubImmOp,
1581 [ "addw", "addsw", "subw", "subsw",
1582 "add", "adds", "sub", "subs"])
1583 generate (LogicalImmOp,
1584 [ "andw", "orrw", "eorw", "andsw",
1585 "and", "orr", "eor", "ands"])
1586
1587 generate (AbsOp, [ "b", "bl" ])
1588
1589 generate (RegAndAbsOp, ["cbzw", "cbnzw", "cbz", "cbnz", "adr", "adrp"])
1590
1591 generate (RegImmAbsOp, ["tbz", "tbnz"])
1592
1593 generate (MoveWideImmOp, ["movnw", "movzw", "movkw", "movn", "movz", "movk"])
1594
1595 generate (BitfieldOp, ["sbfm", "bfmw", "ubfmw", "sbfm", "bfm", "ubfm"])
1596
1597 generate (ExtractOp, ["extrw", "extr"])
1598
1599 generate (CondBranchOp, ["EQ", "NE", "HS", "CS", "LO", "CC", "MI", "PL", "VS", "VC",
1600 "HI", "LS", "GE", "LT", "GT", "LE", "AL", "NV" ])
1601
1602 generate (ImmOp, ["svc", "hvc", "smc", "brk", "hlt", # "dcps1", "dcps2", "dcps3"
1603 ])
1604
1605 generate (Op, ["nop", "yield", "wfe", "sev", "sevl",
1606 "autia1716", "autiasp", "autiaz", "autib1716", "autibsp", "autibz",
1607 "pacia1716", "paciasp", "paciaz", "pacib1716", "pacibsp", "pacibz",
1608 "eret", "drps", "isb", "sb",])
1609
1610 # Ensure the "i" is not stripped off the end of the instruction
1611 generate (PostfixExceptionOp, ["wfi", "xpaclri"])
1612
1613 barriers = ["OSHLD", "OSHST", "OSH", "NSHLD", "NSHST", "NSH",
1614 "ISHLD", "ISHST", "ISH", "LD", "ST", "SY"]
1615
1616 generate (SystemOp, [["dsb", barriers], ["dmb", barriers]])
1617
1618 generate (OneRegOp, ["br", "blr",
1619 "paciza", "pacizb", "pacdza", "pacdzb",
1620 "autiza", "autizb", "autdza", "autdzb", "xpacd",
1621 "braaz", "brabz", "blraaz", "blrabz"])
1622
1623 for system_reg in ["fpsr", "nzcv"]:
1624 generate (SystemOneRegOp, [ ["msr", system_reg] ])
1625
1626 for system_reg in ["fpsr", "nzcv", "dczid_el0", "ctr_el0"]:
1627 generate (OneRegSystemOp, [ ["mrs", system_reg] ])
1628
1629 # Ensure the "i" is not stripped off the end of the instruction
1630 generate (PostfixExceptionOneRegOp, ["xpaci"])
1631
1632 for mode in 'xwhb':
1633 generate (LoadStoreExclusiveOp, [["stxr", mode, 3], ["stlxr", mode, 3],
1634 ["ldxr", mode, 2], ["ldaxr", mode, 2],
1635 ["stlr", mode, 2], ["ldar", mode, 2]])
1636
1637 for mode in 'xw':
1638 generate (LoadStoreExclusiveOp, [["ldxp", mode, 3], ["ldaxp", mode, 3],
1639 ["stxp", mode, 4], ["stlxp", mode, 4]])
1640
1641 for kind in range(6):
1642 sys.stdout.write("\n// " + Address.kindToStr(kind))
1643 if kind != Address.pcrel:
1644 generate (LoadStoreOp,
1645 [["str", "str", kind, "x"], ["str", "str", kind, "w"],
1646 ["str", "strb", kind, "b"], ["str", "strh", kind, "h"],
1647 ["ldr", "ldr", kind, "x"], ["ldr", "ldr", kind, "w"],
1648 ["ldr", "ldrb", kind, "b"], ["ldr", "ldrh", kind, "h"],
1649 ["ldrsb", "ldrsb", kind, "x"], ["ldrsh", "ldrsh", kind, "x"],
1650 ["ldrsh", "ldrsh", kind, "w"], ["ldrsw", "ldrsw", kind, "x"],
1651 ["ldr", "ldr", kind, "d"], ["ldr", "ldr", kind, "s"],
1652 ["str", "str", kind, "d"], ["str", "str", kind, "s"],
1653 ])
1654 else:
1655 generate (LoadStoreOp,
1656 [["ldr", "ldr", kind, "x"], ["ldr", "ldr", kind, "w"]])
1657
1658
1659 for kind in (Address.base_plus_unscaled_offset, Address.pcrel, Address.base_plus_reg, \
1660 Address.base_plus_scaled_offset):
1661 generate (LoadStoreOp,
1662 [["prfm", "prfm\tPLDL1KEEP,", kind, "x"]])
1663
1664 generate(AddSubCarryOp, ["adcw", "adcsw", "sbcw", "sbcsw", "adc", "adcs", "sbc", "sbcs"])
1665
1666 generate(AddSubExtendedOp, ["addw", "addsw", "sub", "subsw", "add", "adds", "sub", "subs"])
1667
1668 generate(ConditionalCompareOp, ["ccmnw", "ccmpw", "ccmn", "ccmp"])
1669 generate(ConditionalCompareImmedOp, ["ccmnw", "ccmpw", "ccmn", "ccmp"])
1670 generate(ConditionalSelectOp,
1671 ["cselw", "csincw", "csinvw", "csnegw", "csel", "csinc", "csinv", "csneg"])
1672
1673 generate(TwoRegOp,
1674 ["rbitw", "rev16w", "revw", "clzw", "clsw", "rbit",
1675 "rev16", "rev32", "rev", "clz", "cls",
1676 "pacia", "pacib", "pacda", "pacdb", "autia", "autib", "autda", "autdb",
1677 "braa", "brab", "blraa", "blrab"])
1678
1679 generate(ThreeRegOp,
1680 ["udivw", "sdivw", "lslvw", "lsrvw", "asrvw", "rorvw", "udiv", "sdiv",
1681 "lslv", "lsrv", "asrv", "rorv", "umulh", "smulh"])
1682 generate(FourRegMulOp,
1683 ["maddw", "msubw", "madd", "msub", "smaddl", "smsubl", "umaddl", "umsubl"])
1684
1685 generate(ThreeRegFloatOp,
1686 [["fabdh", "hhh"], ["fmulh", "hhh"], ["fdivh", "hhh"], ["faddh", "hhh"], ["fsubh", "hhh"],
1687 ["fmaxh", "hhh"], ["fminh", "hhh"], ["fnmulh", "hhh"],
1688 ["fabds", "sss"], ["fmuls", "sss"], ["fdivs", "sss"], ["fadds", "sss"], ["fsubs", "sss"],
1689 ["fmaxs", "sss"], ["fmins", "sss"], ["fnmuls", "sss"],
1690 ["fabdd", "ddd"], ["fmuld", "ddd"], ["fdivd", "ddd"], ["faddd", "ddd"], ["fsubd", "ddd"],
1691 ["fmaxd", "ddd"], ["fmind", "ddd"], ["fnmuld", "ddd"]
1692 ])
1693
1694 generate(FourRegFloatOp,
1695 [["fmaddh", "hhhh"], ["fmadds", "ssss"], ["fmsubs", "ssss"], ["fnmadds", "ssss"],
1696 ["fnmadds", "ssss"], ["fmaddd", "dddd"], ["fmsubd", "dddd"], ["fnmaddd", "dddd"],
1697 ["fnmaddd", "dddd"],])
1698
1699 generate(TwoRegFloatOp,
1700 [["fmovs", "ss"], ["fabss", "ss"], ["fnegs", "ss"], ["fsqrts", "ss"],
1701 ["fcvts", "ds"], ["fcvtsh", "hs"], ["fcvths", "sh"],
1702 ["fmovd", "dd"], ["fabsd", "dd"], ["fnegd", "dd"], ["fsqrtd", "dd"],
1703 ["fcvtd", "sd"], ["fsqrth", "hh"]
1704 ])
1705
1706 generate(FloatConvertOp, [["fcvtzsw", "fcvtzs", "ws"], ["fcvtzs", "fcvtzs", "xs"],
1707 ["fcvtzdw", "fcvtzs", "wd"], ["fcvtzd", "fcvtzs", "xd"],
1708 ["scvtfws", "scvtf", "sw"], ["scvtfs", "scvtf", "sx"],
1709 ["scvtfwd", "scvtf", "dw"], ["scvtfd", "scvtf", "dx"],
1710 ["fcvtassw", "fcvtas", "ws"], ["fcvtasd", "fcvtas", "xd"],
1711 ["fcvtmssw", "fcvtms", "ws"], ["fcvtmsd", "fcvtms", "xd"],
1712 ["fmovs", "fmov", "ws"], ["fmovd", "fmov", "xd"],
1713 ["fmovs", "fmov", "sw"], ["fmovd", "fmov", "dx"]])
1714
1715 generate(TwoRegFloatOp, [["fcmps", "ss"], ["fcmpd", "dd"],
1716 ["fcmps", "sz"], ["fcmpd", "dz"]])
1717
1718 for kind in range(3):
1719 generate(LoadStorePairOp, [["stp", "stp", kind, "w"], ["ldp", "ldp", kind, "w"],
1720 ["ldpsw", "ldpsw", kind, "x"],
1721 ["stp", "stp", kind, "x"], ["ldp", "ldp", kind, "x"]
1722 ])
1723 generate(LoadStorePairOp, [["stnp", "stnp", 0, "w"], ["ldnp", "ldnp", 0, "w"],
1724 ["stnp", "stnp", 0, "x"], ["ldnp", "ldnp", 0, "x"]])
1725
1726 generate(LdStNEONOp, [["ld1", 1, "8B", Address.base_only],
1727 ["ld1", 2, "16B", Address.post],
1728 ["ld1", 3, "1D", Address.post_reg],
1729 ["ld1", 4, "8H", Address.post],
1730 ["ld1r", 1, "8B", Address.base_only],
1731 ["ld1r", 1, "4S", Address.post],
1732 ["ld1r", 1, "1D", Address.post_reg],
1733 ["ld2", 2, "2D", Address.base_only],
1734 ["ld2", 2, "4H", Address.post],
1735 ["ld2r", 2, "16B", Address.base_only],
1736 ["ld2r", 2, "2S", Address.post],
1737 ["ld2r", 2, "2D", Address.post_reg],
1738 ["ld3", 3, "4S", Address.post_reg],
1739 ["ld3", 3, "2S", Address.base_only],
1740 ["ld3r", 3, "8H", Address.base_only],
1741 ["ld3r", 3, "4S", Address.post],
1742 ["ld3r", 3, "1D", Address.post_reg],
1743 ["ld4", 4, "8H", Address.post],
1744 ["ld4", 4, "8B", Address.post_reg],
1745 ["ld4r", 4, "8B", Address.base_only],
1746 ["ld4r", 4, "4H", Address.post],
1747 ["ld4r", 4, "2S", Address.post_reg],
1748 ])
1749
1750 generate(NEONReduceInstruction,
1751 [["addv", "addv", "8B"], ["addv", "addv", "16B"],
1752 ["addv", "addv", "4H"], ["addv", "addv", "8H"],
1753 ["addv", "addv", "4S"],
1754 ["smaxv", "smaxv", "8B"], ["smaxv", "smaxv", "16B"],
1755 ["smaxv", "smaxv", "4H"], ["smaxv", "smaxv", "8H"],
1756 ["smaxv", "smaxv", "4S"], ["fmaxv", "fmaxv", "4S"],
1757 ["sminv", "sminv", "8B"], ["uminv", "uminv", "8B"],
1758 ["sminv", "sminv", "16B"],["uminv", "uminv", "16B"],
1759 ["sminv", "sminv", "4H"], ["uminv", "uminv", "4H"],
1760 ["sminv", "sminv", "8H"], ["uminv", "uminv", "8H"],
1761 ["sminv", "sminv", "4S"], ["uminv", "uminv", "4S"],
1762 ["fminv", "fminv", "4S"],
1763 ["fmaxp", "fmaxp", "2S"], ["fmaxp", "fmaxp", "2D"],
1764 ["fminp", "fminp", "2S"], ["fminp", "fminp", "2D"],
1765 ])
1766
1767 neonFloatCompareWithZeroConditions = ['GT', 'GE', 'EQ', 'LT', 'LE']
1768 neonFloatArrangement = ['2S', '4S', '2D']
1769 neonFloatCompareWithZeroArgs = []
1770 for condition in neonFloatCompareWithZeroConditions:
1771 for currentArrangement in neonFloatArrangement:
1772 currentArgs = [currentArrangement, condition]
1773 neonFloatCompareWithZeroArgs.append(currentArgs)
1774
1775 generate(NEONFloatCompareWithZero, neonFloatCompareWithZeroArgs)
1776
1777 generate(TwoRegNEONOp,
1778 [["absr", "abs", "8B"], ["absr", "abs", "16B"],
1779 ["absr", "abs", "4H"], ["absr", "abs", "8H"],
1780 ["absr", "abs", "2S"], ["absr", "abs", "4S"],
1781 ["absr", "abs", "2D"],
1782 ["fabs", "fabs", "2S"], ["fabs", "fabs", "4S"],
1783 ["fabs", "fabs", "2D"], ["fabs", "fabs", "4H"],
1784 ["fabs", "fabs", "8H"],
1785 ["fneg", "fneg", "2S"], ["fneg", "fneg", "4S"],
1786 ["fneg", "fneg", "2D"], ["fneg", "fneg", "4H"],
1787 ["fneg", "fneg", "8H"],
1788 ["fsqrt", "fsqrt", "2S"], ["fsqrt", "fsqrt", "4S"],
1789 ["fsqrt", "fsqrt", "2D"], ["fsqrt", "fsqrt", "4H"],
1790 ["fsqrt", "fsqrt", "8H"],
1791 ["notr", "not", "8B"], ["notr", "not", "16B"],
1792 ])
1793
1794 generate(ThreeRegNEONOp,
1795 [["andr", "and", "8B"], ["andr", "and", "16B"],
1796 ["orr", "orr", "8B"], ["orr", "orr", "16B"],
1797 ["eor", "eor", "8B"], ["eor", "eor", "16B"],
1798 ["addv", "add", "8B"], ["addv", "add", "16B"],
1799 ["addv", "add", "4H"], ["addv", "add", "8H"],
1800 ["addv", "add", "2S"], ["addv", "add", "4S"],
1801 ["addv", "add", "2D"],
1802 ["sqaddv", "sqadd", "8B"], ["sqaddv", "sqadd", "16B"],
1803 ["sqaddv", "sqadd", "4H"], ["sqaddv", "sqadd", "8H"],
1804 ["sqaddv", "sqadd", "2S"], ["sqaddv", "sqadd", "4S"],
1805 ["sqaddv", "sqadd", "2D"],
1806 ["uqaddv", "uqadd", "8B"], ["uqaddv", "uqadd", "16B"],
1807 ["uqaddv", "uqadd", "4H"], ["uqaddv", "uqadd", "8H"],
1808 ["uqaddv", "uqadd", "2S"], ["uqaddv", "uqadd", "4S"],
1809 ["uqaddv", "uqadd", "2D"],
1810 ["fadd", "fadd", "2S"], ["fadd", "fadd", "4S"],
1811 ["fadd", "fadd", "2D"], ["fadd", "fadd", "4H"],
1812 ["fadd", "fadd", "8H"],
1813 ["subv", "sub", "8B"], ["subv", "sub", "16B"],
1814 ["subv", "sub", "4H"], ["subv", "sub", "8H"],
1815 ["subv", "sub", "2S"], ["subv", "sub", "4S"],
1816 ["subv", "sub", "2D"],
1817 ["sqsubv", "sqsub", "8B"], ["sqsubv", "sqsub", "16B"],
1818 ["sqsubv", "sqsub", "4H"], ["sqsubv", "sqsub", "8H"],
1819 ["sqsubv", "sqsub", "2S"], ["sqsubv", "sqsub", "4S"],
1820 ["sqsubv", "sqsub", "2D"],
1821 ["uqsubv", "uqsub", "8B"], ["uqsubv", "uqsub", "16B"],
1822 ["uqsubv", "uqsub", "4H"], ["uqsubv", "uqsub", "8H"],
1823 ["uqsubv", "uqsub", "2S"], ["uqsubv", "uqsub", "4S"],
1824 ["uqsubv", "uqsub", "2D"],
1825 ["fsub", "fsub", "2S"], ["fsub", "fsub", "4S"],
1826 ["fsub", "fsub", "2D"], ["fsub", "fsub", "4H"],
1827 ["fsub", "fsub", "8H"],
1828 ["mulv", "mul", "8B"], ["mulv", "mul", "16B"],
1829 ["mulv", "mul", "4H"], ["mulv", "mul", "8H"],
1830 ["mulv", "mul", "2S"], ["mulv", "mul", "4S"],
1831 ["fabd", "fabd", "2S"], ["fabd", "fabd", "4S"],
1832 ["fabd", "fabd", "2D"], ["fabd", "fabd", "4H"],
1833 ["fabd", "fabd", "8H"],
1834 ["faddp", "faddp", "2S"], ["faddp", "faddp", "4S"],
1835 ["faddp", "faddp", "2D"], ["faddp", "faddp", "4H"],
1836 ["faddp", "faddp", "8H"],
1837 ["fmul", "fmul", "2S"], ["fmul", "fmul", "4S"],
1838 ["fmul", "fmul", "2D"], ["fmul", "fmul", "4H"],
1839 ["fmul", "fmul", "8H"],
1840 ["mlav", "mla", "4H"], ["mlav", "mla", "8H"],
1841 ["mlav", "mla", "2S"], ["mlav", "mla", "4S"],
1842 ["fmla", "fmla", "2S"], ["fmla", "fmla", "4S"],
1843 ["fmla", "fmla", "2D"], ["fmla", "fmla", "4H"],
1844 ["fmla", "fmla", "8H"],
1845 ["mlsv", "mls", "4H"], ["mlsv", "mls", "8H"],
1846 ["mlsv", "mls", "2S"], ["mlsv", "mls", "4S"],
1847 ["fmls", "fmls", "2S"], ["fmls", "fmls", "4S"],
1848 ["fmls", "fmls", "2D"], ["fmls", "fmls", "4H"],
1849 ["fmls", "fmls", "8H"],
1850 ["fdiv", "fdiv", "2S"], ["fdiv", "fdiv", "4S"],
1851 ["fdiv", "fdiv", "2D"], ["fdiv", "fdiv", "4H"],
1852 ["fdiv", "fdiv", "8H"],
1853 ["maxv", "smax", "8B"], ["maxv", "smax", "16B"],
1854 ["maxv", "smax", "4H"], ["maxv", "smax", "8H"],
1855 ["maxv", "smax", "2S"], ["maxv", "smax", "4S"],
1856 ["umaxv", "umax", "8B"], ["umaxv", "umax", "16B"],
1857 ["umaxv", "umax", "4H"], ["umaxv", "umax", "8H"],
1858 ["umaxv", "umax", "2S"], ["umaxv", "umax", "4S"],
1859 ["smaxp", "smaxp", "8B"], ["smaxp", "smaxp", "16B"],
1860 ["smaxp", "smaxp", "4H"], ["smaxp", "smaxp", "8H"],
1861 ["smaxp", "smaxp", "2S"], ["smaxp", "smaxp", "4S"],
1862 ["fmax", "fmax", "2S"], ["fmax", "fmax", "4S"],
1863 ["fmax", "fmax", "2D"], ["fmax", "fmax", "4H"],
1864 ["fmax", "fmax", "8H"],
1865 ["minv", "smin", "8B"], ["minv", "smin", "16B"],
1866 ["minv", "smin", "4H"], ["minv", "smin", "8H"],
1867 ["minv", "smin", "2S"], ["minv", "smin", "4S"],
1868 ["uminv", "umin", "8B"], ["uminv", "umin", "16B"],
1869 ["uminv", "umin", "4H"], ["uminv", "umin", "8H"],
1870 ["uminv", "umin", "2S"], ["uminv", "umin", "4S"],
1871 ["sminp", "sminp", "8B"], ["sminp", "sminp", "16B"],
1872 ["sminp", "sminp", "4H"], ["sminp", "sminp", "8H"],
1873 ["sminp", "sminp", "2S"], ["sminp", "sminp", "4S"],
1874 ["sqdmulh", "sqdmulh", "4H"], ["sqdmulh", "sqdmulh", "8H"],
1875 ["sqdmulh", "sqdmulh", "2S"], ["sqdmulh", "sqdmulh", "4S"],
1876 ["shsubv", "shsub", "8B"], ["shsubv", "shsub", "16B"],
1877 ["shsubv", "shsub", "4H"], ["shsubv", "shsub", "8H"],
1878 ["shsubv", "shsub", "2S"], ["shsubv", "shsub", "4S"],
1879 ["fmin", "fmin", "2S"], ["fmin", "fmin", "4S"],
1880 ["fmin", "fmin", "2D"], ["fmin", "fmin", "4H"],
1881 ["fmin", "fmin", "8H"],
1882 ["facgt", "facgt", "2S"], ["facgt", "facgt", "4S"],
1883 ["facgt", "facgt", "2D"], ["facgt", "facgt", "4H"],
1884 ["facgt", "facgt", "8H"],
1885 ])
1886
1887 generate(VectorScalarNEONInstruction,
1888 [["fmlavs", "fmla", "2S"], ["mulvs", "mul", "4S"],
1889 ["fmlavs", "fmla", "2D"],
1890 ["fmlsvs", "fmls", "2S"], ["mulvs", "mul", "4S"],
1891 ["fmlsvs", "fmls", "2D"],
1892 ["fmulxvs", "fmulx", "2S"], ["mulvs", "mul", "4S"],
1893 ["fmulxvs", "fmulx", "2D"],
1894 ["mulvs", "mul", "4H"], ["mulvs", "mul", "8H"],
1895 ["mulvs", "mul", "2S"], ["mulvs", "mul", "4S"],
1896 ])
1897
1898 neonVectorCompareInstructionPrefix = ['cm', 'fcm']
1899 neonIntegerVectorCompareConditions = ['GT', 'GE', 'EQ', 'HI', 'HS']
1900 neonFloatVectorCompareConditions = ['EQ', 'GT', 'GE']
1901 neonIntegerArrangement = ['8B', '16B', '4H', '8H', '2S', '4S', '2D']
1902 neonFloatArrangement = ['2S', '4S', '2D']
1903 neonVectorCompareArgs = []
1904 for pre in neonVectorCompareInstructionPrefix:
1905 conditions = neonFloatVectorCompareConditions if pre == 'fcm' else neonIntegerVectorCompareConditions
1906 arrangements = neonFloatArrangement if pre == 'fcm' else neonIntegerArrangement
1907 for condition in conditions:
1908 for currentArrangement in arrangements:
1909 currentArgs = [pre, currentArrangement, condition]
1910 neonVectorCompareArgs.append(currentArgs)
1911
1912 generate(NEONVectorCompare, neonVectorCompareArgs)
1913
1914 generate(SVEComparisonWithZero, ["EQ", "GT", "GE", "LT", "LE", "NE"])
1915
1916 generate(SVEComparisonWithImm, ["EQ", "GT", "GE", "LT", "LE", "NE", "HS", "HI", "LS", "LO"])
1917
1918 generate(SpecialCases, [["ccmn", "__ ccmn(zr, zr, 3u, Assembler::LE);", "ccmn\txzr, xzr, #3, LE"],
1919 ["ccmnw", "__ ccmnw(zr, zr, 5u, Assembler::EQ);", "ccmn\twzr, wzr, #5, EQ"],
1920 ["ccmp", "__ ccmp(zr, 1, 4u, Assembler::NE);", "ccmp\txzr, 1, #4, NE"],
1921 ["ccmpw", "__ ccmpw(zr, 2, 2, Assembler::GT);", "ccmp\twzr, 2, #2, GT"],
1922 ["extr", "__ extr(zr, zr, zr, 0);", "extr\txzr, xzr, xzr, 0"],
1923 ["stlxp", "__ stlxp(r0, zr, zr, sp);", "stlxp\tw0, xzr, xzr, [sp]"],
1924 ["stlxpw", "__ stlxpw(r2, zr, zr, r3);", "stlxp\tw2, wzr, wzr, [x3]"],
1925 ["stxp", "__ stxp(r4, zr, zr, r5);", "stxp\tw4, xzr, xzr, [x5]"],
1926 ["stxpw", "__ stxpw(r6, zr, zr, sp);", "stxp\tw6, wzr, wzr, [sp]"],
1927 ["dup", "__ dup(v0, __ T16B, zr);", "dup\tv0.16b, wzr"],
1928 ["dup", "__ dup(v0, __ S, v1);", "dup\ts0, v1.s[0]"],
1929 ["mov", "__ mov(v1, __ D, 0, zr);", "mov\tv1.d[0], xzr"],
1930 ["mov", "__ mov(v1, __ S, 1, zr);", "mov\tv1.s[1], wzr"],
1931 ["mov", "__ mov(v1, __ H, 2, zr);", "mov\tv1.h[2], wzr"],
1932 ["mov", "__ mov(v1, __ B, 3, zr);", "mov\tv1.b[3], wzr"],
1933 ["smov", "__ smov(r0, v1, __ S, 0);", "smov\tx0, v1.s[0]"],
1934 ["smov", "__ smov(r0, v1, __ H, 1);", "smov\tx0, v1.h[1]"],
1935 ["smov", "__ smov(r0, v1, __ B, 2);", "smov\tx0, v1.b[2]"],
1936 ["umov", "__ umov(r0, v1, __ D, 0);", "umov\tx0, v1.d[0]"],
1937 ["umov", "__ umov(r0, v1, __ S, 1);", "umov\tw0, v1.s[1]"],
1938 ["umov", "__ umov(r0, v1, __ H, 2);", "umov\tw0, v1.h[2]"],
1939 ["umov", "__ umov(r0, v1, __ B, 3);", "umov\tw0, v1.b[3]"],
1940 ["fmov", "__ fmovhid(r0, v1);", "fmov\tx0, v1.d[1]"],
1941 ["fmov", "__ fmovs(v9, __ T2S, 0.5f);", "fmov\tv9.2s, 0.5"],
1942 ["fmov", "__ fmovd(v14, __ T2D, 0.5f);", "fmov\tv14.2d, 0.5"],
1943 ["ld1", "__ ld1(v31, v0, __ T2D, Address(__ post(r1, r0)));", "ld1\t{v31.2d, v0.2d}, [x1], x0"],
1944 ["fcvtzs", "__ fcvtzs(v0, __ T2S, v1);", "fcvtzs\tv0.2s, v1.2s"],
1945 ["fcvtzs", "__ fcvtzs(v0, __ T4H, v1);", "fcvtzs\tv0.4h, v1.4h"],
1946 ["fcvtzs", "__ fcvtzs(v0, __ T8H, v1);", "fcvtzs\tv0.8h, v1.8h"],
1947 ["fcvtas", "__ fcvtas(v2, __ T4S, v3);", "fcvtas\tv2.4s, v3.4s"],
1948 ["fcvtas", "__ fcvtas(v2, __ T4H, v3);", "fcvtas\tv2.4h, v3.4h"],
1949 ["fcvtas", "__ fcvtas(v2, __ T8H, v3);", "fcvtas\tv2.8h, v3.8h"],
1950 ["fcvtms", "__ fcvtms(v4, __ T2D, v5);", "fcvtms\tv4.2d, v5.2d"],
1951 ["fcvtms", "__ fcvtms(v4, __ T4H, v5);", "fcvtms\tv4.4h, v5.4h"],
1952 ["fcvtms", "__ fcvtms(v4, __ T8H, v5);", "fcvtms\tv4.8h, v5.8h"],
1953 # SVE instructions
1954 ["cpy", "__ sve_cpy(z0, __ S, p0, v1);", "mov\tz0.s, p0/m, s1"],
1955 ["cpy", "__ sve_cpy(z0, __ B, p0, 127, true);", "mov\tz0.b, p0/m, 127"],
1956 ["cpy", "__ sve_cpy(z1, __ H, p0, -128, true);", "mov\tz1.h, p0/m, -128"],
1957 ["cpy", "__ sve_cpy(z2, __ S, p0, 32512, true);", "mov\tz2.s, p0/m, 32512"],
1958 ["cpy", "__ sve_cpy(z5, __ D, p0, -32768, false);", "mov\tz5.d, p0/z, -32768"],
1959 ["cpy", "__ sve_cpy(z10, __ B, p0, -1, false);", "mov\tz10.b, p0/z, -1"],
1960 ["cpy", "__ sve_cpy(z11, __ S, p0, -1, false);", "mov\tz11.s, p0/z, -1"],
1961 ["inc", "__ sve_inc(r0, __ S);", "incw\tx0"],
1962 ["dec", "__ sve_dec(r1, __ H);", "dech\tx1"],
1963 ["lsl", "__ sve_lsl(z0, __ B, z1, 7);", "lsl\tz0.b, z1.b, #7"],
1964 ["lsl", "__ sve_lsl(z21, __ H, z1, 15);", "lsl\tz21.h, z1.h, #15"],
1965 ["lsl", "__ sve_lsl(z0, __ S, z1, 31);", "lsl\tz0.s, z1.s, #31"],
1966 ["lsl", "__ sve_lsl(z0, __ D, z1, 63);", "lsl\tz0.d, z1.d, #63"],
1967 ["lsr", "__ sve_lsr(z0, __ B, z1, 7);", "lsr\tz0.b, z1.b, #7"],
1968 ["asr", "__ sve_asr(z0, __ H, z11, 15);", "asr\tz0.h, z11.h, #15"],
1969 ["lsr", "__ sve_lsr(z30, __ S, z1, 31);", "lsr\tz30.s, z1.s, #31"],
1970 ["asr", "__ sve_asr(z0, __ D, z1, 63);", "asr\tz0.d, z1.d, #63"],
1971 ["lsl", "__ sve_lsl(z0, __ B, p0, 0);", "lsl\tz0.b, p0/m, z0.b, #0"],
1972 ["lsl", "__ sve_lsl(z0, __ B, p0, 5);", "lsl\tz0.b, p0/m, z0.b, #5"],
1973 ["lsl", "__ sve_lsl(z1, __ H, p1, 15);", "lsl\tz1.h, p1/m, z1.h, #15"],
1974 ["lsl", "__ sve_lsl(z2, __ S, p2, 31);", "lsl\tz2.s, p2/m, z2.s, #31"],
1975 ["lsl", "__ sve_lsl(z3, __ D, p3, 63);", "lsl\tz3.d, p3/m, z3.d, #63"],
1976 ["lsr", "__ sve_lsr(z0, __ B, p0, 1);", "lsr\tz0.b, p0/m, z0.b, #1"],
1977 ["lsr", "__ sve_lsr(z0, __ B, p0, 8);", "lsr\tz0.b, p0/m, z0.b, #8"],
1978 ["lsr", "__ sve_lsr(z1, __ H, p1, 15);", "lsr\tz1.h, p1/m, z1.h, #15"],
1979 ["lsr", "__ sve_lsr(z2, __ S, p2, 7);", "lsr\tz2.s, p2/m, z2.s, #7"],
1980 ["lsr", "__ sve_lsr(z2, __ S, p2, 31);", "lsr\tz2.s, p2/m, z2.s, #31"],
1981 ["lsr", "__ sve_lsr(z3, __ D, p3, 63);", "lsr\tz3.d, p3/m, z3.d, #63"],
1982 ["asr", "__ sve_asr(z0, __ B, p0, 1);", "asr\tz0.b, p0/m, z0.b, #1"],
1983 ["asr", "__ sve_asr(z0, __ B, p0, 7);", "asr\tz0.b, p0/m, z0.b, #7"],
1984 ["asr", "__ sve_asr(z1, __ H, p1, 5);", "asr\tz1.h, p1/m, z1.h, #5"],
1985 ["asr", "__ sve_asr(z1, __ H, p1, 15);", "asr\tz1.h, p1/m, z1.h, #15"],
1986 ["asr", "__ sve_asr(z2, __ S, p2, 31);", "asr\tz2.s, p2/m, z2.s, #31"],
1987 ["asr", "__ sve_asr(z3, __ D, p3, 63);", "asr\tz3.d, p3/m, z3.d, #63"],
1988 ["addvl", "__ sve_addvl(sp, r0, 31);", "addvl\tsp, x0, #31"],
1989 ["addpl", "__ sve_addpl(r1, sp, -32);", "addpl\tx1, sp, -32"],
1990 ["cntp", "__ sve_cntp(r8, __ B, p0, p1);", "cntp\tx8, p0, p1.b"],
1991 ["dup", "__ sve_dup(z0, __ B, 127);", "dup\tz0.b, 127"],
1992 ["dup", "__ sve_dup(z1, __ H, -128);", "dup\tz1.h, -128"],
1993 ["dup", "__ sve_dup(z2, __ S, 32512);", "dup\tz2.s, 32512"],
1994 ["dup", "__ sve_dup(z7, __ D, -32768);", "dup\tz7.d, -32768"],
1995 ["dup", "__ sve_dup(z10, __ B, -1);", "dup\tz10.b, -1"],
1996 ["dup", "__ sve_dup(z11, __ S, -1);", "dup\tz11.s, -1"],
1997 ["ld1b", "__ sve_ld1b(z0, __ B, p0, Address(sp));", "ld1b\t{z0.b}, p0/z, [sp]"],
1998 ["ld1b", "__ sve_ld1b(z0, __ H, p1, Address(sp));", "ld1b\t{z0.h}, p1/z, [sp]"],
1999 ["ld1b", "__ sve_ld1b(z0, __ S, p2, Address(sp, r8));", "ld1b\t{z0.s}, p2/z, [sp, x8]"],
2000 ["ld1b", "__ sve_ld1b(z0, __ D, p3, Address(sp, 7));", "ld1b\t{z0.d}, p3/z, [sp, #7, MUL VL]"],
2001 ["ld1h", "__ sve_ld1h(z10, __ H, p1, Address(sp, -8));", "ld1h\t{z10.h}, p1/z, [sp, #-8, MUL VL]"],
2002 ["ld1w", "__ sve_ld1w(z20, __ S, p2, Address(r0, 7));", "ld1w\t{z20.s}, p2/z, [x0, #7, MUL VL]"],
2003 ["ld1b", "__ sve_ld1b(z30, __ B, p3, Address(sp, r8));", "ld1b\t{z30.b}, p3/z, [sp, x8]"],
2004 ["ld1w", "__ sve_ld1w(z0, __ S, p4, Address(sp, r28));", "ld1w\t{z0.s}, p4/z, [sp, x28, LSL #2]"],
2005 ["ld1d", "__ sve_ld1d(z11, __ D, p5, Address(r0, r1));", "ld1d\t{z11.d}, p5/z, [x0, x1, LSL #3]"],
2006 ["st1b", "__ sve_st1b(z22, __ B, p6, Address(sp));", "st1b\t{z22.b}, p6, [sp]"],
2007 ["st1b", "__ sve_st1b(z31, __ B, p7, Address(sp, -8));", "st1b\t{z31.b}, p7, [sp, #-8, MUL VL]"],
2008 ["st1b", "__ sve_st1b(z0, __ H, p1, Address(sp));", "st1b\t{z0.h}, p1, [sp]"],
2009 ["st1b", "__ sve_st1b(z0, __ S, p2, Address(sp, r8));", "st1b\t{z0.s}, p2, [sp, x8]"],
2010 ["st1b", "__ sve_st1b(z0, __ D, p3, Address(sp));", "st1b\t{z0.d}, p3, [sp]"],
2011 ["st1w", "__ sve_st1w(z0, __ S, p1, Address(r0, 7));", "st1w\t{z0.s}, p1, [x0, #7, MUL VL]"],
2012 ["st1b", "__ sve_st1b(z0, __ B, p2, Address(sp, r1));", "st1b\t{z0.b}, p2, [sp, x1]"],
2013 ["st1h", "__ sve_st1h(z0, __ H, p3, Address(sp, r8));", "st1h\t{z0.h}, p3, [sp, x8, LSL #1]"],
2014 ["st1d", "__ sve_st1d(z0, __ D, p4, Address(r0, r17));", "st1d\t{z0.d}, p4, [x0, x17, LSL #3]"],
2015 ["ldr", "__ sve_ldr(z0, Address(sp));", "ldr\tz0, [sp]"],
2016 ["ldr", "__ sve_ldr(z31, Address(sp, -256));", "ldr\tz31, [sp, #-256, MUL VL]"],
2017 ["str", "__ sve_str(z8, Address(r8, 255));", "str\tz8, [x8, #255, MUL VL]"],
2018 ["cntb", "__ sve_cntb(r9);", "cntb\tx9"],
2019 ["cnth", "__ sve_cnth(r10);", "cnth\tx10"],
2020 ["cntw", "__ sve_cntw(r11);", "cntw\tx11"],
2021 ["cntd", "__ sve_cntd(r12);", "cntd\tx12"],
2022 ["brka", "__ sve_brka(p2, p0, p2, false);", "brka\tp2.b, p0/z, p2.b"],
2023 ["brka", "__ sve_brka(p1, p2, p3, true);", "brka\tp1.b, p2/m, p3.b"],
2024 ["brkb", "__ sve_brkb(p1, p2, p3, false);", "brkb\tp1.b, p2/z, p3.b"],
2025 ["brkb", "__ sve_brkb(p2, p3, p4, true);", "brkb\tp2.b, p3/m, p4.b"],
2026 ["rev", "__ sve_rev(p0, __ B, p1);", "rev\tp0.b, p1.b"],
2027 ["rev", "__ sve_rev(p1, __ H, p2);", "rev\tp1.h, p2.h"],
2028 ["rev", "__ sve_rev(p2, __ S, p3);", "rev\tp2.s, p3.s"],
2029 ["rev", "__ sve_rev(p3, __ D, p4);", "rev\tp3.d, p4.d"],
2030 ["incp", "__ sve_incp(r0, __ B, p2);", "incp\tx0, p2.b"],
2031 ["whilelt", "__ sve_whilelt(p0, __ B, r1, r28);", "whilelt\tp0.b, x1, x28"],
2032 ["whilele", "__ sve_whilele(p2, __ H, r11, r8);", "whilele\tp2.h, x11, x8"],
2033 ["whilelo", "__ sve_whilelo(p3, __ S, r7, r2);", "whilelo\tp3.s, x7, x2"],
2034 ["whilels", "__ sve_whilels(p4, __ D, r17, r10);", "whilels\tp4.d, x17, x10"],
2035 ["whileltw", "__ sve_whileltw(p1, __ B, r1, r28);", "whilelt\tp1.b, w1, w28"],
2036 ["whilelew", "__ sve_whilelew(p2, __ H, r11, r8);", "whilele\tp2.h, w11, w8"],
2037 ["whilelow", "__ sve_whilelow(p3, __ S, r7, r2);", "whilelo\tp3.s, w7, w2"],
2038 ["whilelsw", "__ sve_whilelsw(p4, __ D, r17, r10);", "whilels\tp4.d, w17, w10"],
2039 ["sel", "__ sve_sel(z0, __ B, p0, z1, z2);", "sel\tz0.b, p0, z1.b, z2.b"],
2040 ["sel", "__ sve_sel(z4, __ D, p0, z5, z6);", "sel\tz4.d, p0, z5.d, z6.d"],
2041 ["cmpeq", "__ sve_cmp(Assembler::EQ, p1, __ B, p0, z0, z1);", "cmpeq\tp1.b, p0/z, z0.b, z1.b"],
2042 ["cmpne", "__ sve_cmp(Assembler::NE, p1, __ H, p0, z2, z3);", "cmpne\tp1.h, p0/z, z2.h, z3.h"],
2043 ["cmpge", "__ sve_cmp(Assembler::GE, p1, __ S, p2, z4, z5);", "cmpge\tp1.s, p2/z, z4.s, z5.s"],
2044 ["cmpgt", "__ sve_cmp(Assembler::GT, p1, __ D, p3, z6, z7);", "cmpgt\tp1.d, p3/z, z6.d, z7.d"],
2045 ["cmphi", "__ sve_cmp(Assembler::HI, p1, __ S, p2, z4, z5);", "cmphi\tp1.s, p2/z, z4.s, z5.s"],
2046 ["cmphs", "__ sve_cmp(Assembler::HS, p1, __ D, p3, z6, z7);", "cmphs\tp1.d, p3/z, z6.d, z7.d"],
2047 ["cmpeq", "__ sve_cmp(Assembler::EQ, p1, __ B, p4, z0, 15);", "cmpeq\tp1.b, p4/z, z0.b, #15"],
2048 ["cmpne", "__ sve_cmp(Assembler::NE, p1, __ H, p0, z2, -16);", "cmpne\tp1.h, p0/z, z2.h, #-16"],
2049 ["cmple", "__ sve_cmp(Assembler::LE, p1, __ S, p1, z4, 0);", "cmple\tp1.s, p1/z, z4.s, #0"],
2050 ["cmplt", "__ sve_cmp(Assembler::LT, p1, __ D, p2, z6, -1);", "cmplt\tp1.d, p2/z, z6.d, #-1"],
2051 ["cmpge", "__ sve_cmp(Assembler::GE, p1, __ S, p3, z4, 5);", "cmpge\tp1.s, p3/z, z4.s, #5"],
2052 ["cmpgt", "__ sve_cmp(Assembler::GT, p1, __ B, p4, z6, -2);", "cmpgt\tp1.b, p4/z, z6.b, #-2"],
2053 ["fcmeq", "__ sve_fcm(Assembler::EQ, p1, __ S, p0, z0, z1);", "fcmeq\tp1.s, p0/z, z0.s, z1.s"],
2054 ["fcmne", "__ sve_fcm(Assembler::NE, p1, __ D, p0, z2, z3);", "fcmne\tp1.d, p0/z, z2.d, z3.d"],
2055 ["fcmgt", "__ sve_fcm(Assembler::GT, p1, __ S, p2, z4, z5);", "fcmgt\tp1.s, p2/z, z4.s, z5.s"],
2056 ["fcmge", "__ sve_fcm(Assembler::GE, p1, __ D, p3, z6, z7);", "fcmge\tp1.d, p3/z, z6.d, z7.d"],
2057 ["uunpkhi", "__ sve_uunpkhi(z0, __ H, z1);", "uunpkhi\tz0.h, z1.b"],
2058 ["uunpklo", "__ sve_uunpklo(z4, __ S, z5);", "uunpklo\tz4.s, z5.h"],
2059 ["sunpkhi", "__ sve_sunpkhi(z6, __ D, z7);", "sunpkhi\tz6.d, z7.s"],
2060 ["sunpklo", "__ sve_sunpklo(z10, __ H, z11);", "sunpklo\tz10.h, z11.b"],
2061 ["scvtf", "__ sve_scvtf(z1, __ D, p0, z0, __ S);", "scvtf\tz1.d, p0/m, z0.s"],
2062 ["scvtf", "__ sve_scvtf(z3, __ D, p1, z2, __ D);", "scvtf\tz3.d, p1/m, z2.d"],
2063 ["scvtf", "__ sve_scvtf(z6, __ S, p2, z1, __ D);", "scvtf\tz6.s, p2/m, z1.d"],
2064 ["scvtf", "__ sve_scvtf(z6, __ S, p3, z1, __ S);", "scvtf\tz6.s, p3/m, z1.s"],
2065 ["scvtf", "__ sve_scvtf(z6, __ H, p3, z1, __ S);", "scvtf\tz6.h, p3/m, z1.s"],
2066 ["scvtf", "__ sve_scvtf(z6, __ H, p3, z1, __ D);", "scvtf\tz6.h, p3/m, z1.d"],
2067 ["scvtf", "__ sve_scvtf(z6, __ H, p3, z1, __ H);", "scvtf\tz6.h, p3/m, z1.h"],
2068 ["fcvt", "__ sve_fcvt(z5, __ D, p3, z4, __ S);", "fcvt\tz5.d, p3/m, z4.s"],
2069 ["fcvt", "__ sve_fcvt(z1, __ S, p3, z0, __ D);", "fcvt\tz1.s, p3/m, z0.d"],
2070 ["fcvt", "__ sve_fcvt(z5, __ S, p3, z4, __ H);", "fcvt\tz5.s, p3/m, z4.h"],
2071 ["fcvt", "__ sve_fcvt(z1, __ H, p3, z0, __ S);", "fcvt\tz1.h, p3/m, z0.s"],
2072 ["fcvt", "__ sve_fcvt(z5, __ D, p3, z4, __ H);", "fcvt\tz5.d, p3/m, z4.h"],
2073 ["fcvt", "__ sve_fcvt(z1, __ H, p3, z0, __ D);", "fcvt\tz1.h, p3/m, z0.d"],
2074 ["fcvtzs", "__ sve_fcvtzs(z19, __ D, p2, z1, __ D);", "fcvtzs\tz19.d, p2/m, z1.d"],
2075 ["fcvtzs", "__ sve_fcvtzs(z9, __ S, p1, z8, __ S);", "fcvtzs\tz9.s, p1/m, z8.s"],
2076 ["fcvtzs", "__ sve_fcvtzs(z1, __ S, p2, z0, __ D);", "fcvtzs\tz1.s, p2/m, z0.d"],
2077 ["fcvtzs", "__ sve_fcvtzs(z1, __ D, p3, z0, __ S);", "fcvtzs\tz1.d, p3/m, z0.s"],
2078 ["fcvtzs", "__ sve_fcvtzs(z1, __ S, p4, z18, __ H);", "fcvtzs\tz1.s, p4/m, z18.h"],
2079 ["lasta", "__ sve_lasta(r0, __ B, p0, z15);", "lasta\tw0, p0, z15.b"],
2080 ["lastb", "__ sve_lastb(r1, __ B, p1, z16);", "lastb\tw1, p1, z16.b"],
2081 ["lasta", "__ sve_lasta(v0, __ B, p0, z15);", "lasta\tb0, p0, z15.b"],
2082 ["lastb", "__ sve_lastb(v1, __ B, p1, z16);", "lastb\tb1, p1, z16.b"],
2083 ["index", "__ sve_index(z6, __ S, 1, 1);", "index\tz6.s, #1, #1"],
2084 ["index", "__ sve_index(z6, __ B, r5, 2);", "index\tz6.b, w5, #2"],
2085 ["index", "__ sve_index(z6, __ H, r5, 3);", "index\tz6.h, w5, #3"],
2086 ["index", "__ sve_index(z6, __ S, r5, 4);", "index\tz6.s, w5, #4"],
2087 ["index", "__ sve_index(z7, __ D, r5, 5);", "index\tz7.d, x5, #5"],
2088 ["cpy", "__ sve_cpy(z7, __ H, p3, r5);", "cpy\tz7.h, p3/m, w5"],
2089 ["tbl", "__ sve_tbl(z16, __ S, z17, z18);", "tbl\tz16.s, {z17.s}, z18.s"],
2090 ["ld1w", "__ sve_ld1w_gather(z15, p0, r5, z16);", "ld1w\t{z15.s}, p0/z, [x5, z16.s, uxtw #2]"],
2091 ["ld1d", "__ sve_ld1d_gather(z15, p0, r5, z16);", "ld1d\t{z15.d}, p0/z, [x5, z16.d, uxtw #3]"],
2092 ["st1w", "__ sve_st1w_scatter(z15, p0, r5, z16);", "st1w\t{z15.s}, p0, [x5, z16.s, uxtw #2]"],
2093 ["st1d", "__ sve_st1d_scatter(z15, p0, r5, z16);", "st1d\t{z15.d}, p0, [x5, z16.d, uxtw #3]"],
2094 ["and", "__ sve_and(p0, p1, p2, p3);", "and\tp0.b, p1/z, p2.b, p3.b"],
2095 ["ands", "__ sve_ands(p4, p5, p6, p0);", "ands\tp4.b, p5/z, p6.b, p0.b"],
2096 ["eor", "__ sve_eor(p0, p1, p2, p3);", "eor\tp0.b, p1/z, p2.b, p3.b"],
2097 ["eors", "__ sve_eors(p5, p6, p0, p1);", "eors\tp5.b, p6/z, p0.b, p1.b"],
2098 ["orr", "__ sve_orr(p0, p1, p2, p3);", "orr\tp0.b, p1/z, p2.b, p3.b"],
2099 ["orrs", "__ sve_orrs(p9, p1, p4, p5);", "orrs\tp9.b, p1/z, p4.b, p5.b"],
2100 ["bic", "__ sve_bic(p10, p7, p9, p11);", "bic\tp10.b, p7/z, p9.b, p11.b"],
2101 ["ptest", "__ sve_ptest(p7, p1);", "ptest\tp7, p1.b"],
2102 ["ptrue", "__ sve_ptrue(p1, __ B);", "ptrue\tp1.b"],
2103 ["ptrue", "__ sve_ptrue(p1, __ B, 0b00001);", "ptrue\tp1.b, vl1"],
2104 ["ptrue", "__ sve_ptrue(p1, __ B, 0b00101);", "ptrue\tp1.b, vl5"],
2105 ["ptrue", "__ sve_ptrue(p1, __ B, 0b01001);", "ptrue\tp1.b, vl16"],
2106 ["ptrue", "__ sve_ptrue(p1, __ B, 0b01101);", "ptrue\tp1.b, vl256"],
2107 ["ptrue", "__ sve_ptrue(p2, __ H);", "ptrue\tp2.h"],
2108 ["ptrue", "__ sve_ptrue(p2, __ H, 0b00010);", "ptrue\tp2.h, vl2"],
2109 ["ptrue", "__ sve_ptrue(p2, __ H, 0b00110);", "ptrue\tp2.h, vl6"],
2110 ["ptrue", "__ sve_ptrue(p2, __ H, 0b01010);", "ptrue\tp2.h, vl32"],
2111 ["ptrue", "__ sve_ptrue(p3, __ S);", "ptrue\tp3.s"],
2112 ["ptrue", "__ sve_ptrue(p3, __ S, 0b00011);", "ptrue\tp3.s, vl3"],
2113 ["ptrue", "__ sve_ptrue(p3, __ S, 0b00111);", "ptrue\tp3.s, vl7"],
2114 ["ptrue", "__ sve_ptrue(p3, __ S, 0b01011);", "ptrue\tp3.s, vl64"],
2115 ["ptrue", "__ sve_ptrue(p4, __ D);", "ptrue\tp4.d"],
2116 ["ptrue", "__ sve_ptrue(p4, __ D, 0b00100);", "ptrue\tp4.d, vl4"],
2117 ["ptrue", "__ sve_ptrue(p4, __ D, 0b01000);", "ptrue\tp4.d, vl8"],
2118 ["ptrue", "__ sve_ptrue(p4, __ D, 0b01100);", "ptrue\tp4.d, vl128"],
2119 ["pfalse", "__ sve_pfalse(p7);", "pfalse\tp7.b"],
2120 ["uzp1", "__ sve_uzp1(p0, __ B, p0, p1);", "uzp1\tp0.b, p0.b, p1.b"],
2121 ["uzp1", "__ sve_uzp1(p0, __ H, p0, p1);", "uzp1\tp0.h, p0.h, p1.h"],
2122 ["uzp1", "__ sve_uzp1(p0, __ S, p0, p1);", "uzp1\tp0.s, p0.s, p1.s"],
2123 ["uzp1", "__ sve_uzp1(p0, __ D, p0, p1);", "uzp1\tp0.d, p0.d, p1.d"],
2124 ["uzp2", "__ sve_uzp2(p0, __ B, p0, p1);", "uzp2\tp0.b, p0.b, p1.b"],
2125 ["uzp2", "__ sve_uzp2(p0, __ H, p0, p1);", "uzp2\tp0.h, p0.h, p1.h"],
2126 ["uzp2", "__ sve_uzp2(p0, __ S, p0, p1);", "uzp2\tp0.s, p0.s, p1.s"],
2127 ["uzp2", "__ sve_uzp2(p0, __ D, p0, p1);", "uzp2\tp0.d, p0.d, p1.d"],
2128 ["punpklo", "__ sve_punpklo(p1, p0);", "punpklo\tp1.h, p0.b"],
2129 ["punpkhi", "__ sve_punpkhi(p1, p0);", "punpkhi\tp1.h, p0.b"],
2130 ["compact", "__ sve_compact(z16, __ S, z16, p1);", "compact\tz16.s, p1, z16.s"],
2131 ["compact", "__ sve_compact(z16, __ D, z16, p1);", "compact\tz16.d, p1, z16.d"],
2132 ["ext", "__ sve_ext(z17, z16, 63);", "ext\tz17.b, z17.b, z16.b, #63"],
2133 ["facgt", "__ sve_fac(Assembler::GT, p1, __ H, p2, z4, z5);", "facgt\tp1.h, p2/z, z4.h, z5.h"],
2134 ["facgt", "__ sve_fac(Assembler::GT, p1, __ S, p2, z4, z5);", "facgt\tp1.s, p2/z, z4.s, z5.s"],
2135 ["facgt", "__ sve_fac(Assembler::GT, p1, __ D, p2, z4, z5);", "facgt\tp1.d, p2/z, z4.d, z5.d"],
2136 ["facge", "__ sve_fac(Assembler::GE, p1, __ H, p2, z4, z5);", "facge\tp1.h, p2/z, z4.h, z5.h"],
2137 ["facge", "__ sve_fac(Assembler::GE, p1, __ S, p2, z4, z5);", "facge\tp1.s, p2/z, z4.s, z5.s"],
2138 ["facge", "__ sve_fac(Assembler::GE, p1, __ D, p2, z4, z5);", "facge\tp1.d, p2/z, z4.d, z5.d"],
2139 # SVE2 instructions
2140 ["histcnt", "__ sve_histcnt(z16, __ S, p0, z16, z16);", "histcnt\tz16.s, p0/z, z16.s, z16.s"],
2141 ["histcnt", "__ sve_histcnt(z17, __ D, p0, z17, z17);", "histcnt\tz17.d, p0/z, z17.d, z17.d"],
2142 ])
2143
2144 print "\n// FloatImmediateOp"
2145 for float in ("2.0", "2.125", "4.0", "4.25", "8.0", "8.5", "16.0", "17.0", "0.125",
2146 "0.1328125", "0.25", "0.265625", "0.5", "0.53125", "1.0", "1.0625",
2147 "-2.0", "-2.125", "-4.0", "-4.25", "-8.0", "-8.5", "-16.0", "-17.0",
2148 "-0.125", "-0.1328125", "-0.25", "-0.265625", "-0.5", "-0.53125", "-1.0", "-1.0625"):
2149 astr = "fmov d0, #" + float
2150 cstr = "__ fmovd(v0, " + float + ");"
2151 print " %-50s //\t%s" % (cstr, astr)
2152 outfile.write("\t" + astr + "\n")
2153
2154 # ARMv8.1A
2155 for size in ("x", "w"):
2156 for suffix in ("", "a", "al", "l"):
2157 generate(LSEOp, [["swp", "swp", size, suffix],
2158 ["ldadd", "ldadd", size, suffix],
2159 ["ldbic", "ldclr", size, suffix],
2160 ["ldeor", "ldeor", size, suffix],
2161 ["ldorr", "ldset", size, suffix],
2162 ["ldsmin", "ldsmin", size, suffix],
2163 ["ldsmax", "ldsmax", size, suffix],
2164 ["ldumin", "ldumin", size, suffix],
2165 ["ldumax", "ldumax", size, suffix]]);
2166
2167 # ARMv8.2A
2168 generate(SHA3SIMDOp, ["bcax", "eor3", "rax1", "xar"])
2169
2170 generate(SHA512SIMDOp, ["sha512h", "sha512h2", "sha512su0", "sha512su1"])
2171
2172 for i in range(6):
2173 generate(SVEBinaryImmOp, ["add", "sub", "and", "eor", "orr"])
2174
2175 generate(SVEVectorOp, [["add", "ZZZ"],
2176 ["sub", "ZZZ"],
2177 ["fadd", "ZZZ"],
2178 ["fmul", "ZZZ"],
2179 ["fsub", "ZZZ"],
2180 ["sqadd", "ZZZ"],
2181 ["sqsub", "ZZZ"],
2182 ["uqadd", "ZZZ"],
2183 ["uqsub", "ZZZ"],
2184 ["abs", "ZPZ", "m"],
2185 ["add", "ZPZ", "m", "dn"],
2186 ["and", "ZPZ", "m", "dn"],
2187 ["asr", "ZPZ", "m", "dn"],
2188 ["bic", "ZPZ", "m", "dn"],
2189 ["clz", "ZPZ", "m"],
2190 ["cnt", "ZPZ", "m"],
2191 ["eor", "ZPZ", "m", "dn"],
2192 ["lsl", "ZPZ", "m", "dn"],
2193 ["lsr", "ZPZ", "m", "dn"],
2194 ["mul", "ZPZ", "m", "dn"],
2195 ["neg", "ZPZ", "m"],
2196 ["not", "ZPZ", "m"],
2197 ["orr", "ZPZ", "m", "dn"],
2198 ["rbit", "ZPZ", "m"],
2199 ["revb", "ZPZ", "m"],
2200 ["smax", "ZPZ", "m", "dn"],
2201 ["smin", "ZPZ", "m", "dn"],
2202 ["umax", "ZPZ", "m", "dn"],
2203 ["umin", "ZPZ", "m", "dn"],
2204 ["sub", "ZPZ", "m", "dn"],
2205 ["fabs", "ZPZ", "m"],
2206 ["fadd", "ZPZ", "m", "dn"],
2207 ["fdiv", "ZPZ", "m", "dn"],
2208 ["fmax", "ZPZ", "m", "dn"],
2209 ["fmin", "ZPZ", "m", "dn"],
2210 ["fmul", "ZPZ", "m", "dn"],
2211 ["fneg", "ZPZ", "m"],
2212 ["frintm", "ZPZ", "m"],
2213 ["frintn", "ZPZ", "m"],
2214 ["frintp", "ZPZ", "m"],
2215 ["fsqrt", "ZPZ", "m"],
2216 ["fsub", "ZPZ", "m", "dn"],
2217 ["fmad", "ZPZZ", "m"],
2218 ["fmla", "ZPZZ", "m"],
2219 ["fmls", "ZPZZ", "m"],
2220 ["fmsb", "ZPZZ", "m"],
2221 ["fnmad", "ZPZZ", "m"],
2222 ["fnmsb", "ZPZZ", "m"],
2223 ["fnmla", "ZPZZ", "m"],
2224 ["fnmls", "ZPZZ", "m"],
2225 ["mla", "ZPZZ", "m"],
2226 ["mls", "ZPZZ", "m"],
2227 ["and", "ZZZ"],
2228 ["eor", "ZZZ"],
2229 ["orr", "ZZZ"],
2230 ["bic", "ZZZ"],
2231 ["uzp1", "ZZZ"],
2232 ["uzp2", "ZZZ"],
2233 ["fabd", "ZPZ", "m", "dn"],
2234 # SVE2 instructions
2235 ["bext", "ZZZ"],
2236 ["bdep", "ZZZ"],
2237 ["eor3", "ZZZ"],
2238 ["sqadd", "ZPZ", "m", "dn"],
2239 ["sqsub", "ZPZ", "m", "dn"],
2240 ["uqadd", "ZPZ", "m", "dn"],
2241 ["uqsub", "ZPZ", "m", "dn"],
2242 ])
2243
2244 generate(SVEReductionOp, [["andv", 0], ["orv", 0], ["eorv", 0], ["smaxv", 0], ["sminv", 0],
2245 ["fminv", 2], ["fmaxv", 2], ["fadda", 2], ["uaddv", 0]])
2246
2247 generate(AddWideNEONOp,
2248 [["saddwv", "saddw", "8H", "8B"], ["saddwv2", "saddw2", "8H", "16B"],
2249 ["saddwv", "saddw", "4S", "4H"], ["saddwv2", "saddw2", "4S", "8H"],
2250 ["saddwv", "saddw", "2D", "2S"], ["saddwv2", "saddw2", "2D", "4S"],
2251 ["uaddwv", "uaddw", "8H", "8B"], ["uaddwv2", "uaddw2", "8H", "16B"],
2252 ["uaddwv", "uaddw", "4S", "4H"], ["uaddwv2", "uaddw2", "4S", "8H"],
2253 ["uaddwv", "uaddw", "2D", "2S"], ["uaddwv2", "uaddw2", "2D", "4S"],
2254 ])
2255
2256 print "\n __ bind(forth);"
2257 outfile.write("forth:\n")
2258
2259 outfile.close()
2260
2261 # compile for sve with armv9-a+sha3+sve2-bitperm because of SHA3 crypto extension and SVE2 bitperm instructions.
2262 # armv9-a enables sve and sve2 by default.
2263 subprocess.check_call([AARCH64_AS, "-march=armv9-a+sha3+sve2-bitperm", "aarch64ops.s", "-o", "aarch64ops.o"])
2264
2265 print
2266 print "/*"
2267 print "*/"
2268
2269 subprocess.check_call([AARCH64_OBJCOPY, "-O", "binary", "-j", ".text", "aarch64ops.o", "aarch64ops.bin"])
2270
2271 infile = open("aarch64ops.bin", "r")
2272 bytes = bytearray(infile.read())
2273
2274 print
2275 print " static const unsigned int insns[] ="
2276 print " {"
2277
2278 i = 0
2279 while i < len(bytes):
2280 print " 0x%02x%02x%02x%02x," % (bytes[i+3], bytes[i+2], bytes[i+1], bytes[i]),
2281 i += 4
2282 if i%16 == 0:
2283 print
2284 print
2285 print " };"
2286 print "// END Generated code -- do not edit"
2287
2288 infile.close()
2289
2290 for f in ["aarch64ops.s", "aarch64ops.o", "aarch64ops.bin"]:
2291 os.remove(f)