From 823040a6bf802af01fe4489c6f118f3111a09d22 Mon Sep 17 00:00:00 2001 From: bzt Date: Mon, 22 Jan 2018 21:31:22 +0100 Subject: [PATCH] New tutorials --- 12_printf/Makefile | 43 + 12_printf/OLVASSEL.md | 43 + 12_printf/README.md | 42 + 12_printf/gpio.h | 45 + 12_printf/kernel8.img | Bin 0 -> 4504 bytes 12_printf/link.ld | 44 + 12_printf/main.c | 43 + 12_printf/mbox.c | 63 ++ 12_printf/mbox.h | 47 + 12_printf/sprintf.c | 148 +++ 12_printf/sprintf.h | 27 + 12_printf/start.S | 149 +++ 12_printf/uart.c | 123 +++ 12_printf/uart.h | 29 + 13_debugger/Makefile | 43 + 13_debugger/OLVASSEL.md | 54 + 13_debugger/README.md | 54 + 13_debugger/dbg.c | 332 ++++++ 13_debugger/dbg.h | 26 + 13_debugger/disasm.h | 2112 +++++++++++++++++++++++++++++++++++++++ 13_debugger/gpio.h | 45 + 13_debugger/kernel8.img | Bin 0 -> 79264 bytes 13_debugger/link.ld | 44 + 13_debugger/main.c | 41 + 13_debugger/mbox.c | 63 ++ 13_debugger/mbox.h | 47 + 13_debugger/sprintf.c | 148 +++ 13_debugger/sprintf.h | 27 + 13_debugger/start.S | 201 ++++ 13_debugger/uart.c | 123 +++ 13_debugger/uart.h | 29 + 31 files changed, 4235 insertions(+) create mode 100644 12_printf/Makefile create mode 100644 12_printf/OLVASSEL.md create mode 100644 12_printf/README.md create mode 100644 12_printf/gpio.h create mode 100755 12_printf/kernel8.img create mode 100644 12_printf/link.ld create mode 100644 12_printf/main.c create mode 100644 12_printf/mbox.c create mode 100644 12_printf/mbox.h create mode 100644 12_printf/sprintf.c create mode 100644 12_printf/sprintf.h create mode 100644 12_printf/start.S create mode 100644 12_printf/uart.c create mode 100644 12_printf/uart.h create mode 100644 13_debugger/Makefile create mode 100644 13_debugger/OLVASSEL.md create mode 100644 13_debugger/README.md create mode 100644 13_debugger/dbg.c create mode 100644 13_debugger/dbg.h create mode 100644 13_debugger/disasm.h create mode 100644 13_debugger/gpio.h create mode 100755 13_debugger/kernel8.img create mode 100644 13_debugger/link.ld create mode 100644 13_debugger/main.c create mode 100644 13_debugger/mbox.c create mode 100644 13_debugger/mbox.h create mode 100644 13_debugger/sprintf.c create mode 100644 13_debugger/sprintf.h create mode 100644 13_debugger/start.S create mode 100644 13_debugger/uart.c create mode 100644 13_debugger/uart.h diff --git a/12_printf/Makefile b/12_printf/Makefile new file mode 100644 index 00000000..f6ba7559 --- /dev/null +++ b/12_printf/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.c=.o) +CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles + +all: clean kernel8.img + +start.o: start.S + aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o + +%.o: %.c + aarch64-elf-gcc $(CFLAGS) -c $< -o $@ + +kernel8.img: start.o $(OBJS) + aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf + aarch64-elf-objcopy -O binary kernel8.elf kernel8.img + +clean: + rm kernel8.elf *.o >/dev/null 2>/dev/null || true diff --git a/12_printf/OLVASSEL.md b/12_printf/OLVASSEL.md new file mode 100644 index 00000000..8ade9998 --- /dev/null +++ b/12_printf/OLVASSEL.md @@ -0,0 +1,43 @@ +Oktatóanyag 12 - Printf +======================= + +Mielőtt kibővítenénk a kivételkezelőnket, szükségünk lesz néhány jól ismert C függvényre. Mivel alacsony szinten +programozunk, nem támaszkodhatunk a libc-re, ezért nekünk kell egy saját printf() implementációt megvalósítanunk. + +```sh +$ qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial stdio +Hello World! +This is character 'A', a hex number: 7FFF and in decimal: 32767 +Padding test: '00007FFF', ' -123' +``` + +Sprintf.h, sprintf.c +-------------------- + +Az érdekes rész. Nagyban ráhagyatkozunk a fordítónk beépített funkcióira, hogy a változó elemszámú paramétereket +lekezeljük. Amint ebben az oktatóanyag sorozatban megszokhattunk, nem a tökéletes kompatibilitásra, hanem a +szükséges minimum implementációra törekszünk. Ezért csak a '%s', '%c', '%d' és '%x' opciókat támogatjuk. Az +igazítás is limitált, csak jobbra lehet igazítani, hexa számokat nullákkal, decimálisakat szóközzel. + +`sprintf(dst, fmt, ...)` ugyanaz, mint a printf, csak az eredményt egy sztringbe rakja + +`vsprintf(dst, fmt, va)` olyan változat, ami paraméterlistát vár változó számú paraméter helyett. + + +Uart.h, uart.c +------------- + +`printf(fmt, ...)` a jó öreg C függvény. A fenti sprintf-et hívja, majd az eredményt ugyanúgy írja ki, mint +ahogy azt az uart_puts() tette. Mivel most már van '%x', az uart_hex() feleslegessé vált, ezért kivettem. + +Start +----- + +Bár mi nem fogunk floatokat és doubleöket használni, a beépített gcc funkciók lehet, hogy használnak. Ezért +engedélyeznünk kell az FPU koprocesszort, hogy ne keletkezzenek "ismeretlen utasítás" kivételek. Továbbá mivel +ebben a példában nincs rendes kivételkezőnk, ezért az `exc_handler` csak egy függvénycsonk ebben a fájlban. + +Main +---- + +Leteszteljük a printf megvalósításunkat. diff --git a/12_printf/README.md b/12_printf/README.md new file mode 100644 index 00000000..ab31faa1 --- /dev/null +++ b/12_printf/README.md @@ -0,0 +1,42 @@ +Tutorial 12 - Printf +==================== + +Before we can improve our exception handler, we are going to need some functions very well known from the C library. +Since we are programming bare metal, we don't have libc, therefore we have to implement printf() on our own. + +```sh +$ qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial stdio +Hello World! +This is character 'A', a hex number: 7FFF and in decimal: 32767 +Padding test: '00007FFF', ' -123' +``` + +Sprintf.h, sprintf.c +-------------------- + +The interesting part. We heavily rely on our compiler's features to handle variable length argument list. As usual +in these tutorials, it's not a fully featured, but rather a bare minimum implementation. Supports '%s', '%c', +'%d' and '%x'. Padding is limited, only right alignment with leading zeros for hex and spaces for decimal. + +`sprintf(dst, fmt, ...)` same as printf, but stores result in a string + +`vsprintf(dst, fmt, va)` a variant that receives an argument list parameter instead of a variable length list of arguments. + + +Uart.h, uart.c +------------- + +`printf(fmt, ...)` the good old C library function. Uses the sprintf function above and then outputs the string +in the same way as uart_puts() did. Since we have '%x', uart_hex() became unnecessary, therefore removed. + +Start +----- + +Although we are not going to use floats and doubles, gcc built-ins might. So we have to enable the FPU +coprocessor to avoid "undefined instruction" exceptions. Also, in a lack of a proper exception handler, +we have a dummy `exc_handler` stub this time. + +Main +---- + +We test our printf implementation. diff --git a/12_printf/gpio.h b/12_printf/gpio.h new file mode 100644 index 00000000..52fa671d --- /dev/null +++ b/12_printf/gpio.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#define MMIO_BASE 0x3F000000 + +#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000)) +#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004)) +#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008)) +#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C)) +#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010)) +#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014)) +#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C)) +#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020)) +#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028)) +#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034)) +#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038)) +#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040)) +#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044)) +#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064)) +#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068)) +#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094)) +#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098)) +#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C)) diff --git a/12_printf/kernel8.img b/12_printf/kernel8.img new file mode 100755 index 0000000000000000000000000000000000000000..a79870b9376e98de3fca549c2184ca4e188879b4 GIT binary patch literal 4504 zcmeHKZA@F&8Gi3Q2V+7Sz+nPqD84o%w9Y0vjSN!-arsDBHPh1ESz4w2Fb1;)L5NIJ zDH~n6n5No9y5K;?q^ja8B)JS`(pxWx=mA?w9?`(&fRlt zlUY;tH@~nrIv?+Qp7(h_&bfyf@+MqdJrf{W@GC4~Syn~hC-kz~>P--T?TqtTx+_WK zbAO=6<+7a#_pi~bI}@EmrEc^|Hg&^UN_Q1TKB=WDL96?)PrXR1Rf(ZwRU$d`MqDk! z7>#VxakaEEL3ANbG<1=~TG_sYOv7<`$GLklWS3r`m*u6(MEHcTQ3%DxL$j8(_XeYhPr*II2Yxs=+hzfqe&U{Os9*J=;&0WqT*l z-I_}ETXhTh(u038ifp>}_dD$39Y(Ph3wUl&uV6c4YTaW(Z1 z=RO6W1Is` z`0+XX6gF*^AA}}^E;65e^njtr29X*%?hsV#e8v()VN#LP~RCc*i{moTQpY=VoeBsyB z@wf1%ov_m(F)sV4-W$Z*c1oqtGn{-2H(Lx@l1JMRhn1AI_bu>Sb5Yq4QRrjj>2l8R zFB$U)p39IQl@N~{cM%VfL&U_q^_A0m67tSVb)!Q6gFLJwc3|c9Y+&7kyiH~YrexOp z@xLt}2M@fvKN}*s_Y|;3k+V+3<0kah!D$Md-n5bL$|D@^c^CHIgM6WcQU^I=n&T_D z?nj>1B|W}aEj2D|CCB`O_VFnXg~Gtx{e#gRB3@Uiyx7)L<84RGUWe`Lh*>5+`zZ8# z)QP<89$hF=Qy;>{3S$TS#Cnf_S3cJ_b6ju1=Wp`4B7RpM#V^bCuaIxV=i;L=_vm@! zIL7J03x+svQN|-i8;eA%nejz|?l7t;6+J-a7bUtQdXUUmU7Imm@{|#+Z8xSX^ro5b z>P@q46q$AEO>@$dr+DS>*oJ8g?X?j4$m?^_rE#~d0)n-oST;cS< zZabMtCVO^mCDUC>W=%Pn)szcI=}+Y7+K|J?{UJ%a9M-!x?O$qw{cl&C)eL^n?%9=!Xl! z@iy=ka)x;q{Ae31G3BjUJXZ%~;GP~_&csF7msu85j0MkStFA$!a9m(0zz}C#$Ry~A zH8ED8w`A2e5cFDLL)a&*5$+^sJ%y-rc*n-R^x(V3-)y=glk*WC5%=nLa{asD)=Vs$bwm=S(xO$KDOQIe@%_{zaqV2B)Xw0ZDvewso$YMPa+ z-uyU>z<&w%hlKktdw0hl#Vud&B=qj0wm0fb_!>n0-L_6^sJSt$k3EmNUS|cKH8i(f z*IY>!A>t97zexj4#O@tYvpF1j`(#|K$;oWYv$?SvY``ikpNtn`9l3O@poWDmFP)4F z-P<^;E@B>z@hW)zm*>A4hLNLc>_P4IwxH%*eN~P{l6qHhH(V8Gfi7svTs4~^PgYE2 za`<%rD}8;>5dHkcQ0eJcg56y`M*@9V3T}BR5DfP8|4KRDeeC#i*ylZgjp%~4 VTSO4^ejDHKXC1lkdY&wQ_#e92q*DL@ literal 0 HcmV?d00001 diff --git a/12_printf/link.ld b/12_printf/link.ld new file mode 100644 index 00000000..1352bfb1 --- /dev/null +++ b/12_printf/link.ld @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +SECTIONS +{ + . = 0x80000; + .text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) } + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) } + PROVIDE(_data = .); + .data : { *(.data .data.* .gnu.linkonce.d*) } + .bss (NOLOAD) : { + . = ALIGN(16); + __bss_start = .; + *(.bss .bss.*) + *(COMMON) + __bss_end = .; + } + _end = .; + + /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) } +} +__bss_size = (__bss_end - __bss_start)>>3; diff --git a/12_printf/main.c b/12_printf/main.c new file mode 100644 index 00000000..f85a98c0 --- /dev/null +++ b/12_printf/main.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "uart.h" + +void main() +{ + // set up serial console + uart_init(); + + // test our printf implementation + printf( "Hello %s!\n" + "This is character '%c', a hex number: %x and in decimal: %d\n" + "Padding test: '%8x', '%8d'\n", + "World", 'A', 32767, 32767, 0x7FFF, -123); + + // echo everything back + while(1) { + uart_send(uart_getc()); + } +} diff --git a/12_printf/mbox.c b/12_printf/mbox.c new file mode 100644 index 00000000..f750c3e4 --- /dev/null +++ b/12_printf/mbox.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "gpio.h" + +/* mailbox message buffer */ +volatile unsigned int __attribute__((aligned(16))) mbox[36]; + +#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880) +#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0)) +#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10)) +#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14)) +#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18)) +#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C)) +#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20)) +#define MBOX_RESPONSE 0x80000000 +#define MBOX_FULL 0x80000000 +#define MBOX_EMPTY 0x40000000 + +/** + * Make a mailbox call. Returns 0 on failure, non-zero on success + */ +int mbox_call(unsigned char ch) +{ + unsigned int r; + /* wait until we can write to the mailbox */ + do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL); + /* write the address of our message to the mailbox with channel identifier */ + *MBOX_WRITE = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF)); + /* now wait for the response */ + while(1) { + /* is there a response? */ + do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY); + r=*MBOX_READ; + /* is it a response to our message? */ + if((unsigned char)(r&0xF)==ch && (r&~0xF)==(unsigned int)((unsigned long)&mbox)) + /* is it a valid successful response? */ + return mbox[1]==MBOX_RESPONSE; + } + return 0; +} diff --git a/12_printf/mbox.h b/12_printf/mbox.h new file mode 100644 index 00000000..09844dea --- /dev/null +++ b/12_printf/mbox.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/* a properly aligned buffer */ +extern volatile unsigned int mbox[36]; + +#define MBOX_REQUEST 0 + +/* channels */ +#define MBOX_CH_POWER 0 +#define MBOX_CH_FB 1 +#define MBOX_CH_VUART 2 +#define MBOX_CH_VCHIQ 3 +#define MBOX_CH_LEDS 4 +#define MBOX_CH_BTNS 5 +#define MBOX_CH_TOUCH 6 +#define MBOX_CH_COUNT 7 +#define MBOX_CH_PROP 8 + +/* tags */ +#define MBOX_TAG_GETSERIAL 0x10004 +#define MBOX_TAG_SETCLKRATE 0x38002 +#define MBOX_TAG_LAST 0 + +int mbox_call(unsigned char ch); diff --git a/12_printf/sprintf.c b/12_printf/sprintf.c new file mode 100644 index 00000000..bc22f3a6 --- /dev/null +++ b/12_printf/sprintf.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/** + * minimal sprintf implementation + */ +unsigned int vsprintf(char *dst, char* fmt, __builtin_va_list args) +{ + long int arg; + int len, sign, i; + char *p, *orig=dst, tmpstr[19]; + + // failsafes + if(dst==(void*)0 || fmt==(void*)0) { + return 0; + } + + // main loop + arg = 0; + while(*fmt) { + // argument access + if(*fmt=='%') { + fmt++; + // literal % + if(*fmt=='%') { + goto put; + } + len=0; + // size modifier + while(*fmt>='0' && *fmt<='9') { + len *= 10; + len += *fmt-'0'; + fmt++; + } + // skip long modifier + if(*fmt=='l') { + fmt++; + } + // character + if(*fmt=='c') { + arg = __builtin_va_arg(args, int); + *dst++ = (char)arg; + fmt++; + continue; + } else + // decimal number + if(*fmt=='d') { + arg = __builtin_va_arg(args, int); + // check input + sign=0; + if((int)arg<0) { + arg*=-1; + sign++; + } + if(arg>99999999999999999L) { + arg=99999999999999999L; + } + // convert to string + i=18; + tmpstr[i]=0; + do { + tmpstr[--i]='0'+(arg%10); + arg/=10; + } while(arg!=0 && i>0); + if(sign) { + tmpstr[--i]='-'; + } + // padding, only space + if(len>0 && len<18) { + while(i>18-len) { + tmpstr[--i]=' '; + } + } + p=&tmpstr[i]; + goto copystring; + } else + // hex number + if(*fmt=='x') { + arg = __builtin_va_arg(args, long int); + // convert to string + i=16; + tmpstr[i]=0; + do { + char n=arg & 0xf; + // 0-9 => '0'-'9', 10-15 => 'A'-'F' + tmpstr[--i]=n+(n>9?0x37:0x30); + arg>>=4; + } while(arg!=0 && i>0); + // padding, only leading zeros + if(len>0 && len<=16) { + while(i>16-len) { + tmpstr[--i]='0'; + } + } + p=&tmpstr[i]; + goto copystring; + } else + // string + if(*fmt=='s') { + p = __builtin_va_arg(args, char*); +copystring: if(p==(void*)0) { + p="(null)"; + } + while(*p) { + *dst++ = *p++; + } + } + } else { +put: *dst++ = *fmt; + } + fmt++; + } + *dst=0; + // number of bytes written + return dst-orig; +} + +/** + * Variable length arguments + */ +unsigned int sprintf(char *dst, char* fmt, ...) +{ + __builtin_va_list args; + __builtin_va_start(args, fmt); + return vsprintf(dst,fmt,args); +} diff --git a/12_printf/sprintf.h b/12_printf/sprintf.h new file mode 100644 index 00000000..2f98dd7c --- /dev/null +++ b/12_printf/sprintf.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +unsigned int sprintf(char *dst, char* fmt, ...); +unsigned int vsprintf(char *dst,char* fmt, __builtin_va_list args); diff --git a/12_printf/start.S b/12_printf/start.S new file mode 100644 index 00000000..1f71f068 --- /dev/null +++ b/12_printf/start.S @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +.section ".text.boot" + +.global _start + +_start: + // read cpu id, stop slave cores + mrs x1, mpidr_el1 + and x1, x1, #3 + cbz x1, 2f + // cpu id > 0, stop +1: wfe + b 1b +2: // cpu id == 0 + + // set stack before our code + ldr x1, =_start + + // set up EL1 + mrs x0, CurrentEL + and x0, x0, #12 // clear reserved bits + + // running at EL3? + cmp x0, #12 + bne 5f + // should never be executed, just for completeness + mov x2, #0x5b1 + msr scr_el3, x2 + mov x2, #0x3c9 + msr spsr_el3, x2 + adr x2, 5f + msr elr_el3, x2 + eret + + // running at EL2? +5: cmp x0, #4 + beq 5f + msr sp_el1, x1 + // enable CNTP for EL1 + mrs x0, cnthctl_el2 + orr x0, x0, #3 + msr cnthctl_el2, x0 + msr cntvoff_el2, xzr + // disable coprocessor traps + mov x0, #0x33FF + msr cptr_el2, x0 + msr hstr_el2, xzr + mov x0, #(3 << 20) + msr cpacr_el1, x0 + // enable AArch64 in EL1 + mov x0, #(1 << 31) // AArch64 + orr x0, x0, #(1 << 1) // SWIO hardwired on Pi3 + msr hcr_el2, x0 + mrs x0, hcr_el2 + // Setup SCTLR access + mov x2, #0x0800 + movk x2, #0x30d0, lsl #16 + msr sctlr_el1, x2 + // set up exception handlers + ldr x2, =_vectors + msr vbar_el1, x2 + // change execution level to EL1 + mov x2, #0x3c4 + msr spsr_el2, x2 + adr x2, 5f + msr elr_el2, x2 + eret + +5: mov sp, x1 + + // clear bss + ldr x1, =__bss_start + ldr w2, =__bss_size +3: cbz w2, 4f + str xzr, [x1], #8 + sub w2, w2, #1 + cbnz w2, 3b + + // jump to C code, should not return +4: bl main + // for failsafe, halt this core too + b 1b + +// a dummy exception handler in this tutorial +exc_handler: + eret + + // important, code has to be properly aligned + .align 11 +_vectors: + // synchronous + .align 7 + mov x0, #0 + mrs x1, esr_el1 + mrs x2, elr_el1 + mrs x3, spsr_el1 + mrs x4, far_el1 + b exc_handler + + // IRQ + .align 7 + mov x0, #1 + mrs x1, esr_el1 + mrs x2, elr_el1 + mrs x3, spsr_el1 + mrs x4, far_el1 + b exc_handler + + // FIQ + .align 7 + mov x0, #2 + mrs x1, esr_el1 + mrs x2, elr_el1 + mrs x3, spsr_el1 + mrs x4, far_el1 + b exc_handler + + // SError + .align 7 + mov x0, #3 + mrs x1, esr_el1 + mrs x2, elr_el1 + mrs x3, spsr_el1 + mrs x4, far_el1 + b exc_handler diff --git a/12_printf/uart.c b/12_printf/uart.c new file mode 100644 index 00000000..758259c6 --- /dev/null +++ b/12_printf/uart.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "gpio.h" +#include "mbox.h" +#include "sprintf.h" + +/* PL011 UART registers */ +#define UART0_DR ((volatile unsigned int*)(MMIO_BASE+0x00201000)) +#define UART0_FR ((volatile unsigned int*)(MMIO_BASE+0x00201018)) +#define UART0_IBRD ((volatile unsigned int*)(MMIO_BASE+0x00201024)) +#define UART0_FBRD ((volatile unsigned int*)(MMIO_BASE+0x00201028)) +#define UART0_LCRH ((volatile unsigned int*)(MMIO_BASE+0x0020102C)) +#define UART0_CR ((volatile unsigned int*)(MMIO_BASE+0x00201030)) +#define UART0_IMSC ((volatile unsigned int*)(MMIO_BASE+0x00201038)) +#define UART0_ICR ((volatile unsigned int*)(MMIO_BASE+0x00201044)) + +// get address from linker +extern volatile unsigned char _end; + +/** + * Set baud rate and characteristics (115200 8N1) and map to GPIO + */ +void uart_init() +{ + register unsigned int r; + + /* initialize UART */ + *UART0_CR = 0; // turn off UART0 + + /* set up clock for consistent divisor values */ + mbox[0] = 8*4; + mbox[1] = MBOX_REQUEST; + mbox[2] = MBOX_TAG_SETCLKRATE; // set clock rate + mbox[3] = 12; + mbox[4] = 8; + mbox[5] = 2; // UART clock + mbox[6] = 4000000; // 4Mhz + mbox[7] = MBOX_TAG_LAST; + mbox_call(MBOX_CH_PROP); + + /* map UART0 to GPIO pins */ + r=*GPFSEL1; + r&=~((7<<12)|(7<<15)); // gpio14, gpio15 + r|=(4<<12)|(4<<15); // alt0 + *GPFSEL1 = r; + *GPPUD = 0; // enable pins 14 and 15 + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = (1<<14)|(1<<15); + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = 0; // flush GPIO setup + + *UART0_ICR = 0x7FF; // clear interrupts + *UART0_IBRD = 2; // 115200 baud + *UART0_FBRD = 0xB; + *UART0_LCRH = 0b11<<5; // 8n1 + *UART0_CR = 0x301; // enable Tx, Rx, FIFO +} + +/** + * Send a character + */ +void uart_send(unsigned int c) { + /* wait until we can send */ + do{asm volatile("nop");}while(*UART0_FR&0x20); + /* write the character to the buffer */ + *UART0_DR=c; +} + +/** + * Receive a character + */ +char uart_getc() { + char r; + /* wait until something is in the buffer */ + do{asm volatile("nop");}while(*UART0_FR&0x10); + /* read it and return */ + r=(char)(*UART0_DR); + /* convert carrige return to newline */ + return r=='\r'?'\n':r; +} + +/** + * Display a string + */ +void printf(char *fmt, ...) { + __builtin_va_list args; + __builtin_va_start(args, fmt); + // we don't have memory allocation yet, so we + // simply place our string after our code + char *s = (char*)&_end; + // use sprintf to format our string + vsprintf(s,fmt,args); + // print out as usual + while(*s) { + /* convert newline to carrige return + newline */ + if(*s=='\n') + uart_send('\r'); + uart_send(*s++); + } +} diff --git a/12_printf/uart.h b/12_printf/uart.h new file mode 100644 index 00000000..577a0be8 --- /dev/null +++ b/12_printf/uart.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +void uart_init(); +void uart_send(unsigned int c); +char uart_getc(); +void printf(char *fmt, ...); diff --git a/13_debugger/Makefile b/13_debugger/Makefile new file mode 100644 index 00000000..f6ba7559 --- /dev/null +++ b/13_debugger/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.c=.o) +CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles + +all: clean kernel8.img + +start.o: start.S + aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o + +%.o: %.c + aarch64-elf-gcc $(CFLAGS) -c $< -o $@ + +kernel8.img: start.o $(OBJS) + aarch64-elf-ld -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf + aarch64-elf-objcopy -O binary kernel8.elf kernel8.img + +clean: + rm kernel8.elf *.o >/dev/null 2>/dev/null || true diff --git a/13_debugger/OLVASSEL.md b/13_debugger/OLVASSEL.md new file mode 100644 index 00000000..91f74b09 --- /dev/null +++ b/13_debugger/OLVASSEL.md @@ -0,0 +1,54 @@ +Oktatóanyag 13 - Debugger +========================= + +Zuzassunk egy nagyot, rakjunk mindjárt egy interaktív debuggert a kivételkezelőbe! :-) Most hogy már van printf(), +nem lesz olyan vészes. + +```sh +$ qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial stdio +Synchronous: Breakpoint instruction +> x +0007FFF0: 13 60 09 00 00 00 00 00 24 10 20 3F 00 00 00 00 .`......$. ?.... +> i x30 x30+64 +00080804: D2800000 movz x0, #0x0 +00080808: 94003D1C bl 0x8FC78 +0008080C: 94003ECF bl 0x90348 +00080810: D69F03E0 eret +00080814: D503201F 27 x nop +> +``` + +Dbg.h, dbg.c +------------ + +Egy nagyon minimális és egyszerű debugger (~300 C sor). + +`breakpoint` újonnan definiált C kulcsszó. Ahová beillesztjük a kódba, ott meghívódik a debugger + +`dbg_decodeexc()` hasonló a 11-es oktatóanyagbeli exc_handler-hez, dekódolja a kivételt kiváltó okot és kiírja + +`dbg_getline()` na ja, mégegy hiányzó függvény. Szükségünk van egy módra, amivel a felhasználó szerkesztheti +a parancssort és ami sztringként visszaadja amit begépelt, mikor Enter-t üt. Szokásunkhoz híven minimál + +`dbg_getoffs()` ez a funkció a parancs paramétereit értelmezi. Elfogad hexa és decimális számot "regiszter+/-offszet" +formátumban + +`dbg_main()` a debugger fő ciklusa. + +Disasm.h +-------- + +Mivel kicsi (~72k), kivételesen könnyű integrálni, mégis minden ARMv8.2-es utasítást ismer, ezért a választásom +az [Universal Disassembler](https://github.com/bztsrc/udisasm)-re esett ehhez az oktatóanyaghoz. Ha nem szeretnél +disassemblert belefordítani a debuggeredbe, akkor a dbg.c fájl elején állítsd a DISASSEMBLER define-t 0-ra. + +Start +----- + +A `_vector` táblánk kicsit máshogy fest. Először is el kell mentenünk a regiszterek értékét a `dbg_saveregs` hívással, +majd kiírjuk a kivétel okát és meghívjuk a mini-debuggerünk fő ciklusát. + +Main +---- + +Leteszteljük az új `breakpoint` kulcsszavunkat C-ben. diff --git a/13_debugger/README.md b/13_debugger/README.md new file mode 100644 index 00000000..04625b6a --- /dev/null +++ b/13_debugger/README.md @@ -0,0 +1,54 @@ +Tutorial 13 - Debugger +====================== + +Let's rock by implementing an interactive debugger in our exception handler! :-) Now that we have printf(), it +shouldn't be hard. + +```sh +$ qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial stdio +Synchronous: Breakpoint instruction +> x +0007FFF0: 13 60 09 00 00 00 00 00 24 10 20 3F 00 00 00 00 .`......$. ?.... +> i x30 x30+64 +00080804: D2800000 movz x0, #0x0 +00080808: 94003D1C bl 0x8FC78 +0008080C: 94003ECF bl 0x90348 +00080810: D69F03E0 eret +00080814: D503201F 27 x nop +> +``` + +Dbg.h, dbg.c +------------ + +A very minimal and simple debugger (~300 lines in C). + +`breakpoint` a newly defined keyword. We can use this anywhere in our code where we want to invoke the debugger + +`dbg_decodeexc()` similar to exc_handler in tutorial 11, decodes the cause of the exception and prints it + +`dbg_getline()` yep, another low level library we're missing. We need a way to allow the user to edit command line +and return it as a string when he/she presses Enter. A minimal implementation, as usual + +`dbg_getoffs()` this function parses the command line for arguments. Accepts hex, decimal number in +"register+/-offset" format + +`dbg_main()` the main loop of the debugger. + +Disasm.h +-------- + +Because it's small (~72k), extremely easy to integrate, yet it supports all ARMv8.2 instructions, I decided to +use the [Universal Disassembler](https://github.com/bztsrc/udisasm) for this tutorial. If you don't want to +compile a disassembler into your debugger, simply set the DISASSEMBLER define 0 in top of dbg.c. + +Start +----- + +Our `_vector` table looks different. We have to save registers in memory with `dbg_saveregs`, print out +the cause of the exception, and call our mini-debugger's main loop. + +Main +---- + +We'll test our shiny new `breakpoint` keyword in C. diff --git a/13_debugger/dbg.c b/13_debugger/dbg.c new file mode 100644 index 00000000..459d5752 --- /dev/null +++ b/13_debugger/dbg.c @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "uart.h" + +#define DISASSEMBLER 1 + +// array to store register values (see dbg_saveregs in start.S) +unsigned long dbg_regs[37]; +// command line +char cmd[256], dbg_running=0; + +#if DISASSEMBLER +/** + * things needed by the disassembler + */ +#include "sprintf.h" +#define NULL ((void*)0) +typedef unsigned long uint64_t; +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; +// include the Universal Disassembler Library +#include "disasm.h" +#endif + +/** + * Decode exception cause + */ +void dbg_decodeexc(unsigned long type) +{ + unsigned char cause=dbg_regs[33]>>26; + + // print out interruption type + switch(type) { + case 0: printf("Synchronous"); break; + case 1: printf("IRQ"); break; + case 2: printf("FIQ"); break; + case 3: printf("SError"); break; + } + printf(": "); + // decode exception type (some, not all. See ARM DDI0487B_b chapter D10.2.28) + switch(cause) { + case 0b000000: printf("Unknown"); break; + case 0b000001: printf("Trapped WFI/WFE"); break; + case 0b001110: printf("Illegal execution"); break; + case 0b010101: printf("System call"); break; + case 0b100000: printf("Instruction abort, lower EL"); break; + case 0b100001: printf("Instruction abort, same EL"); break; + case 0b100010: printf("Instruction alignment fault"); break; + case 0b100100: printf("Data abort, lower EL"); break; + case 0b100101: printf("Data abort, same EL"); break; + case 0b100110: printf("Stack alignment fault"); break; + case 0b101100: printf("Floating point"); break; + case 0b110000: printf("Breakpoint, lower EL"); break; + case 0b110001: printf("Breakpoint, same EL"); break; + case 0b111100: printf("Breakpoint instruction"); break; + default: printf("Unknown %x", cause); break; + } + // decode data abort cause + if(cause==0b100100 || cause==0b100101) { + printf(", "); + switch((dbg_regs[33]>>2)&0x3) { + case 0: printf("Address size fault"); break; + case 1: printf("Translation fault"); break; + case 2: printf("Access flag fault"); break; + case 3: printf("Permission fault"); break; + } + switch(dbg_regs[33]&0x3) { + case 0: printf(" at level 0"); break; + case 1: printf(" at level 1"); break; + case 2: printf(" at level 2"); break; + case 3: printf(" at level 3"); break; + } + } + printf("\n"); + // if the exception happened in the debugger, we stop to avoid infinite loop + if(dbg_running) { + printf("Exception in debugger!\n" + " elr_el1: %x spsr_el1: %x\n esr_el1: %x far_el1: %x\nsctlr_el1: %x tcr_el1: %x\n", + dbg_regs[31],dbg_regs[32],dbg_regs[33],dbg_regs[34],dbg_regs[35],dbg_regs[36]); + while(1); + } +} + +/** + * helper to read a line from user. We redefine some control caracters to handle CSI + * \e[3~ = 1, delete + * \e[D = 2, cursor left + * \e[C = 3, cursor right + */ +void dbg_getline() +{ + int i,cmdidx=0,cmdlast=0; + char c; + cmd[0]=0; + // prompt + printf("\r> "); + // read until Enter pressed + while((c=uart_getc())!='\n') { + // decode CSI key sequences (some, not all) + if(c==27) { + c=uart_getc(); + if(c=='[') { + c=uart_getc(); + if(c=='C') c=3; else // left + if(c=='D') c=2; else // right + if(c=='3') { + c=uart_getc(); + if(c=='~') c=1; // delete + } + } + } + // Backspace + if(c==8 || c==127) { + if(cmdidx>0) { + cmdidx--; + for(i=cmdidx;i0) cmdidx--; + } else + // cursor right + if(c==3) { + if(cmdidx=sizeof(cmd)-1) { + continue; + } + // if we're not appending, move bytes after cursor + if(cmdidxcmdidx;i--) + cmd[i]=cmd[i-1]; + } + cmdlast++; + cmd[cmdidx++]=c; + } + cmd[cmdlast]=0; + // display prompt and command line, place cursor with CSI code + printf("\r> %s \r\e[%dC",cmd,cmdidx+2); + } + printf("\n"); +} + +/** + * helper function to parse the command line for arguments + */ +unsigned long dbg_getoffs(int i) +{ + unsigned long base=0,ret=0; + int j=0,sign=0; + // if starts with a register + if(cmd[i]=='x' || cmd[i]=='r') { + i++; if(cmd[i]>='0' && cmd[i]<='9') { j=cmd[i]-'0'; } + i++; if(cmd[i]>='0' && cmd[i]<='9') { j*=10; j+=cmd[i]-'0'; } + if(j>=0 && j<37) base=dbg_regs[j]; + i++; + if(cmd[i]=='-') { i++; sign++; } + if(cmd[i]=='+') i++; + } + // offset part + if(cmd[i]=='0' && cmd[i+1]=='x') { + i+=2; + // hex value + while((cmd[i]>='0'&&cmd[i]<='9')||(cmd[i]>='a'&&cmd[i]<='f')||(cmd[i]>='A'&&cmd[i]<='F')) { + ret <<= 4; + if(cmd[i]>='0' && cmd[i]<='9') ret += cmd[i]-'0'; + else if(cmd[i] >= 'a' && cmd[i] <= 'f') ret += cmd[i]-'a'+10; + else if(cmd[i] >= 'A' && cmd[i] <= 'F') ret += cmd[i]-'A'+10; + i++; + } + } else { + // decimal value + while(cmd[i]>='0'&&cmd[i]<='9'){ + ret *= 10; + ret += cmd[i++]-'0'; + } + } + // return base + offset + return sign? base-ret : base+ret; +} + +/** + * main loop, get and parse commands + */ +void dbg_main() +{ + unsigned long os=0, oe=0, a; + char c; +#if DISASSEMBLER + char str[64]; +#endif + int i; + + dbg_running++; + + // main debugger loop + while(1) { + // get command from user + dbg_getline(); + // parse commands + if(cmd[0]==0 || cmd[0]=='?' || cmd[0]=='h') { + // print help + printf("Mini debugger commands:\n" + " ?/h\t\tthis help\n" + " r\t\tdump registers\n" + " x [os [oe]]\texamine memory from offset start (os) to offset end (oe)\n" + " i [os [oe]]\tdisassemble instruction from offset start to offset end\n" + " c\t\tcontinue execution\n"); + continue; + } else + // continue execution + if(cmd[0]=='c') { + // move instruction pointer, skip over 'brk' + asm volatile ("msr elr_el1, %0" : : "r" (dbg_regs[31]+4)); + break; + } else + // dump registers + if(cmd[0]=='r') { + // general purpose registers x0-x30 + for(i=0;i<31;i++) { + if(i && i%3==0) printf("\n"); + if(i<10) printf(" "); + printf("x%d: %16x ",i,dbg_regs[i]); + } + // some system registers + printf("elr_el1: %x spsr_el1: %x\n esr_el1: %x far_el1: %x\nsctlr_el1: %x tcr_el1: %x\n", + dbg_regs[31],dbg_regs[32],dbg_regs[33],dbg_regs[34],dbg_regs[35],dbg_regs[36]); + continue; + } else + // examine or disassemble, commands with arguments + if(cmd[0]=='x' || cmd[0]=='i') { + i=1; + // get first argument + while(cmd[i]!=0 && cmd[i]!=' ') i++; // skip command + while(cmd[i]!=0 && cmd[i]==' ') i++; // skip separators + if(cmd[i]!=0) { + os=oe=dbg_getoffs(i); + // get second argument + while(cmd[i]!=0 && cmd[i]!=' ') i++; // skip 1st arg + while(cmd[i]!=0 && cmd[i]==' ') i++; // skip separators + if(cmd[i]!=0) { + oe=dbg_getoffs(i); + } + } else { + // no arguments, use defaults + if(cmd[0]=='i') { + // elr or lr (x30) + os=oe=dbg_regs[31]?dbg_regs[31]:dbg_regs[30]; + } else { + // sp (x29) + os=oe=dbg_regs[29]; + } + } + // do the thing + if(cmd[0]=='i') { + // must be multiple of 4 + os=os&~3L; + oe=(oe+3)&~3L; + if(oe<=os) oe=os+4; + // disassemble AArch64 bytecode + while(os=127?'.':c); + } + printf("\n"); + } + } + continue; + } else { + printf("ERROR: unknown command.\n"); + } + } + dbg_running--; +} diff --git a/13_debugger/dbg.h b/13_debugger/dbg.h new file mode 100644 index 00000000..7788f9e7 --- /dev/null +++ b/13_debugger/dbg.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#define breakpoint asm volatile("brk #0") diff --git a/13_debugger/disasm.h b/13_debugger/disasm.h new file mode 100644 index 00000000..7700d2e5 --- /dev/null +++ b/13_debugger/disasm.h @@ -0,0 +1,2112 @@ +/* Universal Disassembler Function Library + * https://github.com/bztsrc/udisasm + * + * ----- GENERATED FILE, DO NOT EDIT! ----- + * + * Copyright (C) 2017 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * @brief Disassembler source generated from aarch64.txt + */ + +enum { disasm_arg_NONE,disasm_arg_ofs,disasm_arg_ofe, disasm_arg_Xt, disasm_arg_labelij1, disasm_arg_RtS, disasm_arg_RnS, disasm_arg_i, disasm_arg_j12_opt, disasm_arg_Rn, disasm_arg_Rt, disasm_arg_j16_opt, disasm_arg_j, disasm_arg_Rm, disasm_arg_c, disasm_arg_labeli4, disasm_arg_i_opt, disasm_arg_pstate, disasm_arg_sh, disasm_arg_a0, disasm_arg_a1, disasm_arg_a2, disasm_arg_dc0, disasm_arg_dc1, disasm_arg_ZVA, disasm_arg_dc2, disasm_arg_ic, disasm_arg_Xt_opt, disasm_arg_tl0, disasm_arg_tl1, disasm_arg_tl2, disasm_arg_sysreg, disasm_arg_Cn, disasm_arg_Cm, disasm_arg_Xn, disasm_arg_b, disasm_arg_VtT, disasm_arg_Vt2T, disasm_arg_Vt3T, disasm_arg_Vt4T, disasm_arg_offs, disasm_arg_XnS, disasm_arg_offe, disasm_arg_Qi, disasm_arg_Xm, disasm_arg_Qi3, disasm_arg_Qi2, disasm_arg_Qi1, disasm_arg_VtB, disasm_arg_VtH, disasm_arg_VtS, disasm_arg_VtD, disasm_arg_i1, disasm_arg_i2, disasm_arg_i4, disasm_arg_i8, disasm_arg_Vt3B, disasm_arg_Vt3H, disasm_arg_Vt3S, disasm_arg_Vt3D, disasm_arg_i3, disasm_arg_i6, disasm_arg_i12, disasm_arg_i24, disasm_arg_Vt2B, disasm_arg_Vt2H, disasm_arg_Vt2S, disasm_arg_Vt2D, disasm_arg_i16, disasm_arg_Vt4B, disasm_arg_Vt4H, disasm_arg_Vt4S, disasm_arg_Vt4D, disasm_arg_i32, disasm_arg_z, disasm_arg_z3, disasm_arg_z2, disasm_arg_z4, disasm_arg_Rd, disasm_arg_Rd1, disasm_arg_Rt1, disasm_arg_Wd, disasm_arg_Wt, disasm_arg_FPt, disasm_arg_prf_op, disasm_arg_is4_opt, disasm_arg_FPm, disasm_arg_iz4_opt, disasm_arg_im4_opt, disasm_arg_nRt, disasm_arg_FPst, disasm_arg_j_opt, disasm_arg_Rom, disasm_arg_amountj, disasm_arg_amountz, disasm_arg_amountjs, disasm_arg_amountj2, disasm_arg_amountj3, disasm_arg_shiftj_opt, disasm_arg_Rsom, disasm_arg_exts, disasm_arg_Wn, disasm_arg_Wm, disasm_arg_Xd, disasm_arg_Vt16b, disasm_arg_Vn16b, disasm_arg_Qt, disasm_arg_Sn, disasm_arg_Vm4s, disasm_arg_Vt4s, disasm_arg_Vn4s, disasm_arg_Qn, disasm_arg_St, disasm_arg_FPjt, disasm_arg_Vnj, disasm_arg_FPidx, disasm_arg_Vtjq, disasm_arg_Ht, disasm_arg_Hn, disasm_arg_Hm, disasm_arg_FPn, disasm_arg_VtH1, disasm_arg_VnH1, disasm_arg_VmH1, disasm_arg_Vtzq, disasm_arg_Vnzq, disasm_arg_Vmzq, disasm_arg_simd0, disasm_arg_FPz2t, disasm_arg_FPz2n, disasm_arg_FPz2m, disasm_arg_VnT, disasm_arg_VmT, disasm_arg_FPz3t, disasm_arg_FPz3n, disasm_arg_FPz4n, disasm_arg_VnT3, disasm_arg_Vn2d, disasm_arg_Vn2h, disasm_arg_Vnz, disasm_arg_FPz4t, disasm_arg_Vtz, disasm_arg_FPz3m, disasm_arg_Dt, disasm_arg_Dn, disasm_arg_shrshift, disasm_arg_Vtj2, disasm_arg_Vnj2, disasm_arg_shlshift, disasm_arg_FPnj, disasm_arg_VnTa, disasm_arg_FPjt2, disasm_arg_FPjn2, disasm_arg_Vtz3, disasm_arg_VmTs, disasm_arg_VmHs, disasm_arg_VmTs2, disasm_arg_Vn116b, disasm_arg_Vn216b, disasm_arg_Vn316b, disasm_arg_Vn416b, disasm_arg_Vtj, disasm_arg_R2n, disasm_arg_FPidxk, disasm_arg_Vtzq2, disasm_arg_VnT2, disasm_arg_Vnz3, disasm_arg_Vnzq2, disasm_arg_shift8, disasm_arg_VtT3, disasm_arg_VmT3, disasm_arg_VtT4, disasm_arg_imm8, disasm_arg_amountk_opt, disasm_arg_amountk2_opt, disasm_arg_imm64, disasm_arg_Vt2d, disasm_arg_F16, disasm_arg_F32, disasm_arg_F64, disasm_arg_VmTs4b, disasm_arg_Vm2d, disasm_arg_Vm16b, disasm_arg_Vd16b, disasm_arg_Vd4s, disasm_arg_FPz5t, disasm_arg_fbits, disasm_arg_FPz5n, disasm_arg_Vn1d, disasm_arg_Vt1d, disasm_arg_FPk5t, disasm_arg_FPz5m, disasm_arg_jz, disasm_arg_FPz5d }; + +/*** private functions ***/ +char *disasm_str(char*s,int n) {if(!s)return "?";while(n){s++;if(!*s){s++;n--;}}return *s?s:"?";}; +char *disasm_sysreg(uint8_t p,uint8_t k,uint8_t n,uint8_t m,uint8_t j) {char *t=NULL;switch(p){case 2: switch(k) {case 0: switch(n) {case 0: switch(m) {case 0: t="?\0?\0OSDTRRX_EL1\0"; break;case 2: t="MDCCINT_EL1\0?\0MDSCR_EL1\0"; break;case 3: t="?\0?\0OSDTRTX_EL1\0"; break;case 6: t="?\0?\0OSECCR_EL1\0"; break;default: { n=j; j=m; switch(n) {case 4: t="DBGBVR0_EL1\0DBGBVR1_EL1\0DBGBVR2_EL1\0DBGBVR3_EL1\0DBGBVR4_EL1\0DBGBVR5_EL1\0DBGBVR6_EL1\0DBGBVR7_EL1\0"; break;case 5: t="DBGBCR0_EL1\0DBGBCR1_EL1\0DBGBCR2_EL1\0DBGBCR3_EL1\0DBGBCR4_EL1\0DBGBCR5_EL1\0DBGBCR6_EL1\0DBGBCR7_EL1\0"; break;case 6: t="DBGWVR0_EL1\0DBGWVR1_EL1\0DBGWVR2_EL1\0DBGWVR3_EL1\0DBGWVR4_EL1\0DBGWVR5_EL1\0DBGWVR6_EL1\0DBGWVR7_EL1\0"; break;case 7: t="DBGWCR0_EL1\0DBGWCR1_EL1\0DBGWCR2_EL1\0DBGWCR3_EL1\0DBGWCR4_EL1\0DBGWCR5_EL1\0DBGWCR6_EL1\0DBGWCR7_EL1\0"; break;} break; }} break;case 1: if(m==0) t="MDRAR_EL1\0?\0?\0?\0OSLAR_EL1\0"; else if(j==4) { j=m; t="OSLSR_EL1\0?\0OSDLR_EL1\0DBGPRCR_EL1\0"; }break;case 7: if(j==6) { j=m; t="?\0?\0?\0?\0?\0?\0?\0?\0DBGCLAIMSET_EL1\0DBGCLAIMCLR_EL1\0?\0?\0?\0?\0DBGAUTHSTATUS_EL1\0"; }break;} break;case 3: if(n==0&&j==0) { j=m; t="?\0MDCCSR_EL0\0?\0?\0DBGDTR_EL0\0DBGDTRRX_EL0\0"; } break;case 4: if(n==0&&m==7) t="DBGVCR32_EL2\0"; break;} break;case 3: switch(k) {case 0: switch(n) {case 0: if(m==0) t="MIDR_EL1\0?\0?\0?\0?\0MPIDR_EL1\0REVIDR_EL1\0?\0ID_PFR0_EL1\0ID_PFR1_EL1\0ID_DFR0_EL1\0ID_AFR0_EL1\0ID_MMFR0_EL1\0ID_MMFR1_EL1\0ID_MMFR2_EL1\0ID_MMFR3_EL1\0ID_ISAR0_EL1\0ID_ISAR1_EL1\0ID_ISAR2_EL1\0ID_ISAR2_EL1\0ID_ISAR3_EL1\0ID_ISAR4_EL1\0ID_ISAR5_EL1\0ID_MMFR4_EL1\0?\0MVFR0_EL1\0MVFR1_EL1\0MVFR2_EL1\0?\0?\0?\0?\0?\0ID_AA64PFR0_EL1\0ID_AA64PFR1_EL1\0?\0?\0ID_AA64ZFR0_EL1\0?\0?\0?\0ID_AA64DFR0_EL1\0ID_AA64DFR1_EL1\0?\0?\0ID_AA64AFR0_EL1\0ID_AA64AFR1_EL1\0?\0?\0ID_AA64ISAR0_EL1\0ID_AA64ISAR1_EL1\0?\0?\0?\0?\0?\0?\0ID_AA64MMFR0_EL1\0ID_AA64MMFR1_EL1\0ID_AA64MMFR2_EL1\0"; break;case 1: switch(m) {case 0: t="SCTLR_EL1\0ACTLR_EL1\0CPACR_EL1\0"; break;case 2: t="ZCR_EL1\0"; break;} break;case 2: if(m==0) t="TTBR0_EL1\0TTBR1_EL1\0TCR_EL1\0"; break;case 4: switch(m) {case 0: t="SPSR_EL1\0ELR_EL1\0"; break;case 1: t="SP_EL0\0"; break;case 2: t="SPSel\0?\0CurrentEL\0PAN\0UAO\0"; break;case 6: t="ICC_PMR_EL1\0"; break;} break;case 5: switch(m) {case 1: t="AFSR0_EL1\0AFSR1_EL1\0"; break;case 2: t="ESR_EL1"; break;case 3: t="ERRIDR_EL1\0ERRSELR_EL1\0"; break;case 4: t="ERXFR_EL1\0ERXCTLR_EL1\0ERXSTATUS_EL1\0ERXADDR_EL1\0"; break;case 5: t="ERXMISC0_EL1\0ERXMISC1_EL1\0"; break;} break;case 6: if(m==0) t="FAR_EL1\0"; break;case 7: if(m==4) t="PAR_EL1\0"; break;case 9: switch(m) {case 9: t="PMSCR_EL1\0?\0PMSICR_EL1\0PMSIRR_EL1\0PMSFCR_EL1\0PMSEVFR_EL1\0PMSLATFR_EL1\0PMSIDR_EL1\0PMSIDR_EL1\0"; break;case 10: t="PMBLIMITR_EL1\0PMBPTR_EL1\0?\0PMBSR_EL1\0?\0?\0?\0PMBIDR_EL1\0"; break;case 14: t="?\0PMINTENSET_EL1\0PMINTENCLR_EL1\0"; break;} break;case 10: if(m==4) t="LORSA_EL1\0LOREA_EL1\0LORN_EL1\0LORC_EL1\0?\0?\0?\0LORID_EL1\0"; else if(m!=4&&j==0) { j=m; t="?\0?\0MAIR_EL1\0AMAIR_EL1\0"; }break;case 12: switch(m) {case 0: t="VBAR_EL1\0RVBAR_EL1\0RMR_EL1\0"; break;case 1: t="ISR_EL1\0DISR_EL1\0"; break;case 8: t="ICC_IAR0_EL1\0ICC_EOIR0_EL1\0ICC_HPPIR0_EL1\0ICC_BPR0_EL1\0ICC_AP0R0_EL1\0ICC_AP0R1_EL1\0ICC_AP0R2_EL1\0ICC_AP0R3_EL1\0"; break;case 9: t="ICC_AP1R0_EL1\0ICC_AP1R1_EL1\0ICC_AP1R2_EL1\0ICC_AP1R3_EL1\0"; break;case 11: t="?\0ICC_DIR_EL1\0?\0ICC_RPR_EL1\0?\0ICC_SGI1R_EL1\0ICC_ASGI1R_EL1\0ICC_SGI0R_EL1\0"; break;case 12: t="ICC_IAR1_EL1\0ICC_EOIR1_EL1\0ICC_HPPIR1_EL1\0ICC_BPR1_EL1\0ICC_CTLR_EL1\0ICC_SRE_EL1\0ICC_IGRPEN0_EL1\0ICC_IGRPEN1_EL1\0"; break;} break;case 13: if(m==0) t="?\0CONTEXTIDR_EL1\0?\0?\0TPIDR_EL1\0"; break;case 14: if(m==1) t="CNTKCTL_EL1\0"; break;} break;case 1: if(n==0&&m==0) t="CCSIDR_EL1\0CLIDR_EL1\0?\0?\0?\0?\0?\0AIDR_EL1\0"; break;case 2: if(n==0&&m==0) t="CSSELR_EL1\0"; break;case 3: switch(n) {case 0: if(m==0) t="?\0CTR_EL0\0?\0?\0?\0?\0?\0DCZID_EL0\0"; break;case 4: switch(m) {case 2: t="NZCV\0DAIF\0"; break;case 4: t="FPCR\0FPSR\0"; break;case 5: t="DSPSR_EL0\0DLR_EL0\0"; break;} break;case 9: switch(m) {case 12: t="PMCR_EL0\0PMCNTENSET_EL0\0PMCNTENCLR_EL0\0PMOVSCLR_EL0\0PMSWINC_EL0\0PMSELR_EL0\0PMCEID0_EL0\0PMCEID1_EL0\0"; break;case 13: t="PMCCNTR_EL0\0PMXEVTYPER_EL0\0PMXEVCNTR_EL0\0"; break;case 14: t="PMUSERENR_EL0\0?\0?\0PMOVSSET_EL0\0"; break;} break; +case 13: if(m==0) t="?\0?\0TPIDR_EL0\0TPIDRRO_EL0\0"; break;case 14: switch(m) {case 0: t="CNTFRQ_EL0\0CNTPCT_EL0\0CNTVCT_EL0\0"; break;case 2: t="CNTP_TVAL_EL0\0CNTP_CTL_EL0\0CNTP_CVAL_EL0\0"; break;case 3: t="CNTV_TVAL_EL0\0CNTV_CTL_EL0\0CNTV_CVAL_EL0\0"; break;} break;} break;case 4: switch(n) {case 0: if(m==0) t="VPIDR_EL2\0?\0?\0?\0?\0VMPIDR_EL2\0"; break;case 1: switch(m) {case 0: t="SCTLR_EL2\0ACTLR_EL2\0"; break;case 1: t="HCR_EL2\0MDCR_EL2\0CPTR_EL2\0HSTR_EL2\0?\0?\0?\0HACR_EL2\0"; break;case 2: t="ZCR_EL2\0"; break;} break;case 2: switch(m) {case 0: t="TTBR0_EL2\0?\0TCR_EL2\0"; break;case 1: t="VTTBR0_EL2\0?\0VTCR_EL2\0"; break;} break;case 3: if(m==0) t="DACR32_EL2\0"; break;case 4: switch(m) {case 0: t="SPSR_EL2\0ELR_EL2\0"; break;case 1: t="SP_EL1\0"; break;case 3: t="SPSR_irq\0SPSR_abt\0SPSR_und\0SPSR_fiq\0"; break;} break;case 5: switch(m) {case 0: t="?\0IFSR32_EL2\0"; break;case 1: t="AFSR0_EL2\0AFSR1_EL2\0"; break;case 2: t="ESR_EL2\0?\0?\0VSESR_EL2\0"; break;case 3: t="FPEXC32_EL2\0"; break;} break;case 6: if(m==0) t="FAR_EL2\0?\0?\0?\0HPFAR_EL2\0"; break;case 9: if(m==9) t="PMSCR_EL2\0"; break;case 10: switch(m) {case 2: t="MAIR_EL2\0"; break;case 3: t="AMAIR_EL2\0"; break;} break;case 12: switch(m) {case 0: t="VBAR_EL2\0RVBAR_EL2\0RMR_EL2\0"; break;case 1: t="?\0VDISR_EL2\0"; break;case 8: t="ICH_AP0R0_EL2\0ICH_AP0R1_EL2\0ICH_AP0R2_EL2\0ICH_AP0R3_EL2\0"; break;case 9: t="ICH_AP1R0_EL2\0ICH_AP1R1_EL2\0ICH_AP1R2_EL2\0ICH_AP1R3_EL2\0ICC_SRE_EL2\0"; break;case 11: t="ICH_HCR_EL2\0ICH_VTR_EL2\0ICH_MISR_EL2\0ICH_EISR_EL2\0?\0ICH_ELRSR_EL2\0?\0ICH_VMCR_EL2\0"; break;case 12: t="ICH_LR0_EL2\0ICH_LR1_EL2\0ICH_LR2_EL2\0ICH_LR3_EL2\0ICH_LR4_EL2\0ICH_LR5_EL2\0ICH_LR6_EL2\0ICH_LR7_EL2\0"; break;case 13: t="ICH_LR8_EL2\0ICH_LR9_EL2\0ICH_LR10_EL2\0ICH_LR11_EL2\0ICH_LR12_EL2\0ICH_LR13_EL2\0ICH_LR14_EL2\0ICH_LR15_EL2\0"; break;} break;case 13: if(m==0) t="?\0CONTEXTIDR_EL2\0TPIDR_EL2\0"; break;case 14: switch(m) {case 0: t="?\0?\0?\0CNTVOFF_EL2\0"; break;case 1: t="CNTHCTL_EL2\0"; break;case 2: t="CNTHP_TVAL_EL2\0CNTHP_CTL_EL2\0CNTHP_CVAL_EL2\0"; break;case 3: t="CNTHV_TVAL_EL2\0CNTHV_CTL_EL2\0CNTHV_CVAL_EL2\0"; break;} break;} break;case 5: if(n==4&&m==0) t="SPSR_EL12\0ELR_EL12\0"; break;case 6: if(n==4&&m==1) t="SP_EL2\0"; break;case 7: if(n==14&&m==2) t="CNTPS_TVAL_EL1\0CNTPS_CTL_EL1\0CNTPS_CVAL_EL1\0"; break;} break;}return t?disasm_str(t,j):NULL;} + +/*** public API ***/ +uint64_t disasm(uint64_t addr, char *str) +{ + uint32_t i=0; + uint16_t op=0, om=0, j=0; + uint8_t t=0, s=0, n=0, m=0, c=0, p=0, a=0, d=0, k=0, b=0, q=0, z=0, o=0; + uint32_t ic32; + uint64_t iaddr=addr; + char *names=NULL,*olds=str; + char *pstate="?\0?\0?\0uao\0pan\0spsel\0daifs\0daifc\0"; + char *conds="eq\0ne\0cs\0cc\0mi\0pl\0vs\0vc\0hi\0ls\0ge\0lt\0gt\0le\0al\0nv\0"; + char *share="?\0oshld\0oshst\0osh\0?\0nshld\0nshst\0nsh\0?\0ishld\0ishst\0ish\0?\0ld\0st\0sy\0"; + char *at_op0="s1e1r\0s1e1w\0s1e0r\0s1e0w\0"; + char *at_op1="s1e1rp\0s1e1wp\0"; + char *at_op2="s1e2r\0s1e2w\0?\0?\0s12e1r\0s12e1w\0s12e0r\0s12e0w\0s1e3r\0s1e3w\0"; + char *dc_op0="?\0ivac\0isw\0"; + char *dc_op1="csw\0cisw\0"; + char *dc_op2="cvac\0cvau\0civac\0"; + char *ic_op="ialluis\0iallu\0?\0ivau\0"; + char *tlbi_op0="vmalle1is\0vae1is\0aside1is\0vaae1is\0?\0vale1is\0?\0vaale1is\0vmalle1\0vae1\0aside1\0vaae1\0?\0vale1\0?\0vaale1\0alle2is\0vae2is\0?\0?\0alle1is\0vale2is\0vmalls12e1is\0alle2\0vae2\0?\0?\0alle1\0vale2\0vmalls12e1\0"; + char *tlbi_op1="ipas2e1is\0ipas2le1is\0ipas2e1\0ipas2el1\0"; + char *tlbi_op2="alle3is\0vae3is\0?\0vale3is\0alle3\0vae3\0?\0vale3\0"; + char *quantum="8b\016b\04h\08h\02s\04s\01d\02d\01q\02q\0"; + char *prf_typ="pld\0pli\0pst\0"; + char *prf_pol="keep\0strm\0"; + char *extend32="uxtb\0uxth\0lsl\0uxtx\0sxtb\0sxth\0sxtw\0sxtx\0"; + char *extend64="uxtb\0uxth\0uxtw\0lsl\0sxtb\0sxth\0sxtw\0sxtx\0"; + char *shift="lsl\0lsr\0asr\0ror\0"; + uint8_t args[9]={0,0,0,0,0,0,0,0,0}; + + ic32=*((uint32_t*)addr); + + //handle multiple NOPs at once + if(ic32==0b11010101000000110010000000011111) { + while(*((uint32_t*)addr)==ic32) { op++; addr+=4; } + if(str!=NULL) str+=sprintf(str," %d x nop",op); + *str=0; + return addr; + } + + //decode instruction + if(((ic32>>8)&0b111111110000000001111100)==0b000010000000000001111100) { + names="stxrb\0stlxrb\0?\0?\0?\0?\0?\0?\0?\0?\0casb\0caslb\0?\0?\0casab\0casalb\0"; + op=((ic32>>20)&0xe)|((ic32>>15)&0x1); d=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wd; args[1]=disasm_arg_Wt; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b111111111011111111111100)==0b000011100010000101101000) { + names="fcvtn\0"; + z=((ic32>>22)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_Vtzq2; args[1]=disasm_arg_Vnz3; + } else + if(((ic32>>8)&0b111111111011111111111100)==0b000011100010000111101000) { + names="fcvtl\0"; + z=((ic32>>22)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_Vtz3; args[1]=disasm_arg_Vnzq2; + } else + if(((ic32>>8)&0b111111110011111111111100)==0b000011100010000100101000) { + names="xtn\0"; + z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT2; + } else + if(((ic32>>8)&0b111111110011111111111100)==0b000011100010000100111000) { + names="shll\0"; + z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_Vtz; args[1]=disasm_arg_VnT; args[2]=disasm_arg_shift8; + } else + if(((ic32>>8)&0b111111110010000010011100)==0b000011100010000010010000) { + names="sqdmlal\0sqdmlsl\0sqdmull\0"; + op=((ic32>>13)&0x3); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_Vtz; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b111111111100000010110100)==0b000011110100000000100000) { + names="smlal\0smlsl\0"; + op=((ic32>>14)&0x1); j=((ic32>>9)&0x4)|((ic32>>20)&0x3); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1;q=0; + args[0]=disasm_arg_Vtz3; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111100000011110100)==0b000011110100000010100000) { + names="smull\0"; + j=((ic32>>9)&0x4)|((ic32>>20)&0x3); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1;q=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111100000010110100)==0b000011111000000000100000) { + names="smlal\0smlsl\0"; + op=((ic32>>14)&0x1); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2;q=0; + args[0]=disasm_arg_Vtz3; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111100000011110100)==0b000011111000000010100000) { + names="smull\0"; + j=((ic32>>10)&0x2)|((ic32>>21)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2;q=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111111111111111100)==0b000111100110001001000000) { + names="fcvt\0"; + n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_St; args[1]=disasm_arg_Dn; + } else + if(((ic32>>8)&0b111111110011111001111100)==0b000111100010001001000000) { + names="fcvt\0"; + z=((ic32>>22)&0x3); k=((ic32>>15)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPk5t; args[1]=disasm_arg_FPz5n; + } else + if(((ic32>>8)&0b111111110011100001111100)==0b000111100010000001000000) { + names="fmov\0fabs\0fneg\0fsqrt\0?\0?\0?\0?\0frintn\0frintp\0frintm\0frintz\0frinta\0?\0frintx\0frinti\0"; + op=((ic32>>15)&0xf); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz5t; args[1]=disasm_arg_FPz5n; + } else + if((ic32&0b11111111001000001111110000001111)==0b00011110001000000010000000000000) { + names="fcmp\0fcmpe\0"; + op=((ic32>>4)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); + args[0]=disasm_arg_FPz5n; args[1]=disasm_arg_FPz5m; + } else + if((ic32&0b11111111001000001111110000001111)==0b00011110001000000010000000001000) { + names="fcmp\0fcmpe\0"; + op=((ic32>>4)&0x1); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); + args[0]=disasm_arg_FPz5n; args[1]=disasm_arg_simd0; + } else + if((ic32&0b11111111001000000001111111100000)==0b00011110001000000001000000000000) { + names="fmov\0"; + z=((ic32>>22)&0x3); j=((ic32>>13)&0xff); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz5t; args[1]=disasm_arg_jz; + } else + if(((ic32>>8)&0b111111110010000000001100)==0b000111100010000000000100) { + names="ffcmp\0ffcmpe\0"; + op=((ic32>>4)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); c=((ic32>>12)&0xf); n=((ic32>>5)&0x1f); j=((ic32>>0)&0xf); + args[0]=disasm_arg_FPz5n; args[1]=disasm_arg_FPz5m; args[2]=disasm_arg_j; args[3]=disasm_arg_c; + } else + if(((ic32>>8)&0b111111110010000000001100)==0b000111100010000000001000) { + names="fmul\0fdiv\0fadd\0fsub\0fmax\0fmin\0fmaxnm\0fminmn\0fnmul\0"; + op=((ic32>>12)&0xf); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz5t; args[1]=disasm_arg_FPz5n; args[2]=disasm_arg_FPz5m; + } else + if(((ic32>>8)&0b111111110010000000001100)==0b000111100010000000001100) { + names="fcsel\0"; + z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); c=((ic32>>12)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz5t; args[1]=disasm_arg_FPz5n; args[2]=disasm_arg_FPz5m; args[3]=disasm_arg_c; + } else + if(((ic32>>24)&0b11111111)==0b00011111) { + names="fmadd\0fmsub\0fnmadd\0fnmsub\0"; + op=((ic32>>20)&0x2)|((ic32>>15)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); d=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz5t; args[1]=disasm_arg_FPz5n; args[2]=disasm_arg_FPz5m; args[3]=disasm_arg_FPz5t; args[4]=disasm_arg_FPz5n; args[5]=disasm_arg_FPz5d; + } else + if(((ic32>>8)&0b111111111111100011111100)==0b001011110000000011100100) { + names="movi\0"; + j=((ic32>>11)&0xe0)|((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Dt; args[1]=disasm_arg_imm64; + } else + if(((ic32>>8)&0b111111110010000000001100)==0b001110000010000000000000) { + names="ldaddb\0ldclrb\0ldeorb\0ldsetb\0ldsmaxb\0ldsminb\0ldumaxb\0lduminb\0swpb\0?\0?\0?\0?\0?\0?\0?\0ldaddlb\0ldclrlb\0ldeorlb\0ldsetlb\0ldsmaxlb\0ldsminlb\0ldumaxlb\0lduminlb\0swplb\0?\0?\0?\0?\0?\0?\0?\0ldaddab\0ldclrab\0ldeorab\0ldsetab\0ldsmaxab\0ldsminab\0ldumaxab\0lduminab\0swpab\0?\0?\0?\0?\0?\0?\0?\0ldaddalb\0ldclralb\0ldeoralb\0ldsetalb\0ldsmaxalb\0ldsminalb\0ldumaxalb\0lduminalb\0swpalb\0"; + op=((ic32>>18)&0x30)|((ic32>>12)&0xf); d=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wd; args[1]=disasm_arg_Wt; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b110111110011111110011100)==0b000011100010000100001000) { + names="?\0xtn\0sqxtn\0?\0?\0sqxtun\0uqxtn\0fcvtxn\0"; + op=((ic32>>27)&0x4)|((ic32>>13)&0x3); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT3; + } else + if(((ic32>>8)&0b110111110010000011011100)==0b000011100010000000010000) { + names="saddw\0ssubw\0uaddw\0usubw\0"; + op=((ic32>>28)&0x2)|((ic32>>13)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_VtT3; args[1]=disasm_arg_VnT3; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b110111110010000011011100)==0b000011100010000001000000) { + names="addhn\0subhn\0raddhn\0rsubhn\0"; + op=((ic32>>28)&0x2)|((ic32>>13)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT3; args[2]=disasm_arg_VmT3; + } else + if(((ic32>>8)&0b110111110010000011111100)==0b000011100010000011100000) { + names="pmull\0umull\0"; + op=((ic32>>29)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_VtT4; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b110111110010000000001100)==0b000011100010000000000000) { + names="saddl\0saddw\0ssubl\0ssubw\0addhn\0sabal\0subhn\0sabdl\0smlal\0sqdmlal\0smlsl\0sqdmlsl\0?\0sqdmull\0pmull\0?\0uaddl\0uaddw\0usubl\0usubw\0raddhn\0uabal\0rsubhn\0uabdl\0umlal\0?\0umlsl\0?\0?\0?\0umull\0"; + op=((ic32>>25)&0x10)|((ic32>>12)&0xf); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_VtT3; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b110111111100000000100100)==0b000011110100000000100000) { + names="smlal\0sqdmlal\0smlsl\0sqdmlsl\0smull\0sqdmull\0?\0?\0umlal\0?\0umlsl\0?\0umull\0"; + op=((ic32>>26)&0x8)|((ic32>>13)&0x6)|((ic32>>12)&0x1); j=((ic32>>9)&0x4)|((ic32>>20)&0x3); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1;q=0; + args[0]=disasm_arg_Vtz; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b110111111000000011100100)==0b000011110000000010000100) { + names="?\0rshrn\0sqshrn\0sqrshrn\0sqshrun\0sqrshrun\0uqshrn\0uqrshrn\0"; + op=((ic32>>27)&0x4)|((ic32>>11)&0x3); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_Vtj2; args[1]=disasm_arg_VnTa; args[2]=disasm_arg_shrshift; + } else + if(((ic32>>8)&0b110111111000000011111100)==0b000011110000000010100100) { + names="sshll\0usshll\0"; + op=((ic32>>29)&0x1); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=0; + args[0]=disasm_arg_Vtj2; args[1]=disasm_arg_VnTa; args[2]=disasm_arg_shlshift; + } else + if(((ic32>>8)&0b110111111100000000100100)==0b000011111000000000100000) { + names="smlal\0sqdmlal\0smlsl\0sqdmlsl\0smull\0sqdmull\0?\0?\0umlal\0?\0umlsl\0?\0umull\0"; + op=((ic32>>26)&0x8)|((ic32>>13)&0x6)|((ic32>>12)&0x1); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2;q=0; + args[0]=disasm_arg_Vtz; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111110000000001111100)==0b010010000000000001111100) { + names="stxrh\0stlxrh\0?\0?\0?\0?\0?\0?\0?\0?\0cash\0caslh\0?\0?\0casah\0casalh\0"; + op=((ic32>>20)&0xe)|((ic32>>15)&0x1); d=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wd; args[1]=disasm_arg_Wt; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b111111111110000011111100)==0b010011100000000000011100) { + names="ins\0"; + j=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtj; args[1]=disasm_arg_offs; args[2]=disasm_arg_FPidx; args[3]=disasm_arg_offe; args[4]=disasm_arg_R2n; + } else + if(((ic32>>8)&0b111111111111111111001100)==0b010011100010100001001000) { + names="aese\0aesd\0aesmc\0aesimc\0"; + op=((ic32>>12)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt16b; args[1]=disasm_arg_Vn16b; + } else + if(((ic32>>8)&0b111111111011111111111100)==0b010011100010000101101000) { + names="fcvtn2\0"; + z=((ic32>>22)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_Vtzq2; args[1]=disasm_arg_Vnz3; + } else + if(((ic32>>8)&0b111111111011111111111100)==0b010011100010000111101000) { + names="fcvtl2\0"; + z=((ic32>>22)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_Vtz3; args[1]=disasm_arg_Vnzq2; + } else + if(((ic32>>8)&0b111111110011111111111100)==0b010011100010000100101000) { + names="xtn2\0"; + z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT2; + } else + if(((ic32>>8)&0b111111110011111111111100)==0b010011100010000100111000) { + names="shll2\0"; + z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_Vtz; args[1]=disasm_arg_VnT; args[2]=disasm_arg_shift8; + } else + if(((ic32>>8)&0b111111110010000010011100)==0b010011100010000010010000) { + names="sqdmlal2\0sqdmlsl2\0sqdmull2\0"; + op=((ic32>>13)&0x3); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_Vtz; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b111111111100000010110100)==0b010011110100000000100000) { + names="smlal2\0smlsl2\0"; + op=((ic32>>14)&0x1); j=((ic32>>9)&0x4)|((ic32>>20)&0x3); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1;q=1; + args[0]=disasm_arg_Vtz3; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111100000011110100)==0b010011110100000010100000) { + names="smull2\0"; + j=((ic32>>9)&0x4)|((ic32>>20)&0x3); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1;q=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111100000010110100)==0b010011111000000000100000) { + names="smlal2\0smlsl2\0"; + op=((ic32>>14)&0x1); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2;q=1; + args[0]=disasm_arg_Vtz3; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111100000011110100)==0b010011111000000010100000) { + names="smull2\0"; + j=((ic32>>10)&0x2)|((ic32>>21)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2;q=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if((ic32&0b11111111000000000000000000010000)==0b01010100000000000000000000000000) { + names="b.%s\0"; + i=((ic32>>23)&1?(-1<<19):0)|((ic32>>5)&0x7ffff); c=((ic32>>0)&0xf); + args[0]=disasm_arg_labeli4; + } else + if(((ic32>>8)&0b111111111110000011111100)==0b010111100000000000000100) { + names="dup\0"; + j=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPjt; args[1]=disasm_arg_Vnj; args[2]=disasm_arg_offs; args[3]=disasm_arg_FPidx; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b111111111110000011111100)==0b010111100000000000110000) { + names="sha1su0\0"; + m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4s; args[1]=disasm_arg_Vn4s; args[2]=disasm_arg_Vm4s; + } else + if(((ic32>>8)&0b111111111110000011001100)==0b010111100000000000000000) { + names="sha1c\0sha1p\0sha1m\0sha1su0\0"; + op=((ic32>>12)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Qt; args[1]=disasm_arg_Sn; args[2]=disasm_arg_Vm4s; + } else + if(((ic32>>8)&0b111111111110000011101100)==0b010111100000000001000000) { + names="sha256h\0sha256h2\0"; + op=((ic32>>12)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Qt; args[1]=disasm_arg_Qn; args[2]=disasm_arg_Vm4s; + } else + if(((ic32>>8)&0b111111111110000011111100)==0b010111100000000001100000) { + names="sha256su1\0"; + m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4s; args[1]=disasm_arg_Vn4s; args[2]=disasm_arg_Vm4s; + } else + if(((ic32>>8)&0b111111111111111111111100)==0b010111100010100000001000) { + names="sha1h\0"; + n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_St; args[1]=disasm_arg_Sn; + } else + if(((ic32>>8)&0b111111111111111111111100)==0b010111100010100000011000) { + names="sha1su1\0"; + n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4s; args[1]=disasm_arg_Vn4s; + } else + if(((ic32>>8)&0b111111111111111111111100)==0b010111100010100000101000) { + names="sha256su0\0"; + n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4s; args[1]=disasm_arg_Vn4s; + } else + if(((ic32>>8)&0b111111111110000011111100)==0b010111100100000000011100) { + names="fmulx\0"; + m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Ht; args[1]=disasm_arg_Hn; args[2]=disasm_arg_Hm; + } else + if(((ic32>>8)&0b111111111110000011111100)==0b010111100100000000100100) { + names="fcmeq\0"; + m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Ht; args[1]=disasm_arg_Hn; args[2]=disasm_arg_Hm; + } else + if(((ic32>>8)&0b111111111010000011111100)==0b010111100010000011011100) { + names="fmulx\0"; + z=((ic32>>22)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPn; args[2]=disasm_arg_FPm; + } else + if(((ic32>>8)&0b111111111010000011111100)==0b010111100010000011100100) { + names="fcmeq\0"; + z=((ic32>>22)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPn; args[2]=disasm_arg_FPm; + } else + if(((ic32>>8)&0b111111110111111111001100)==0b010111100011000011001000) { + names="fmaxnmp\0faddp\0?\0fmaxp\0fminnmp\0?\0?\0fminp\0"; + op=((ic32>>21)&0x4)|((ic32>>12)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Ht; args[1]=disasm_arg_Vn2h; + } else + if(((ic32>>8)&0b111111110110000011111100)==0b010111100100000000111100) { + names="frecps\0frsqrts\0"; + op=((ic32>>23)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Ht; args[1]=disasm_arg_Hn; args[2]=disasm_arg_Hm; + } else + if(((ic32>>8)&0b111111110011111111111100)==0b010111100011000110111000) { + names="addp\0"; + z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz3t; args[1]=disasm_arg_Vn2d; + } else + if(((ic32>>8)&0b111111110010000011111100)==0b010111100010000011111100) { + names="frecps\0frsqrts\0"; + op=((ic32>>23)&0x1); z=((ic32>>22)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPn; args[2]=disasm_arg_FPm; + } else + if(((ic32>>8)&0b111111110010000010011100)==0b010111100010000010010000) { + names="sqdmlal\0sqdmlsl\0sqdmull\0"; + op=((ic32>>13)&0x3); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz4t; args[1]=disasm_arg_FPz2n; args[2]=disasm_arg_FPz2m; + } else + if(((ic32>>8)&0b111111111100000011100100)==0b010111110100000011000000) { + names="sqdmulh\0sqrdmulh\0"; + op=((ic32>>12)&0x1); j=((ic32>>9)&0x4)|((ic32>>20)&0x3); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_FPz4t; args[1]=disasm_arg_FPz4n; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111100000000110100)==0b010111110100000000110000) { + names="sqdmlal\0sqdmlsl\0sqdmull\0"; + op=((ic32>>14)&0x3); j=((ic32>>9)&0x4)|((ic32>>20)&0x3); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_FPz4t; args[1]=disasm_arg_FPz3n; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111000000011011100)==0b010111110000000001010100) { + names="shl\0sqshl\0"; + op=((ic32>>13)&0x1); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Dt; args[1]=disasm_arg_Dn; args[2]=disasm_arg_shlshift; + } else + if(((ic32>>8)&0b111111111100000011100100)==0b010111111000000011000000) { + names="sqdmulh\0sqrdmulh\0"; + op=((ic32>>12)&0x1); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2; + args[0]=disasm_arg_FPz4t; args[1]=disasm_arg_FPz4n; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111100000000110100)==0b010111111000000000110000) { + names="sqdmlal\0sqdmlsl\0sqdmull\0"; + op=((ic32>>14)&0x3); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2; + args[0]=disasm_arg_FPz4t; args[1]=disasm_arg_FPz3n; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>16)&0b1111111111000000)==0b0110100011000000) { + names="ldpsw\0"; + i=((ic32>>21)&1?(-1<<7):0)|((ic32>>15)&0x7f); m=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_Xm; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; args[5]=disasm_arg_im4_opt; + } else + if(((ic32>>16)&0b1111111101000000)==0b0110100101000000) { + names="ldpsw\0"; + p=((ic32>>23)&0x1); i=((ic32>>21)&1?(-1<<7):0)|((ic32>>15)&0x7f); m=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_Xm; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_im4_opt; args[5]=disasm_arg_offe; + } else + if(((ic32>>8)&0b111111111110000010000100)==0b011011100000000000000100) { + names="ins\0"; + j=((ic32>>16)&0x1f); k=((ic32>>11)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtj; args[1]=disasm_arg_offs; args[2]=disasm_arg_FPidx; args[3]=disasm_arg_offe; args[4]=disasm_arg_Vnj; args[5]=disasm_arg_offs; args[6]=disasm_arg_FPidxk; args[7]=disasm_arg_offe; + } else + if(((ic32>>8)&0b111111110011111111001100)==0b011011100011000011001000) { + names="fmaxnmv\0?\0?\0fmaxv\0fminnmv\0?\0?\0fminv\0"; + op=((ic32>>21)&0x4)|((ic32>>12)&0x3); z=((ic32>>22)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_Vn4s; + } else + if(((ic32>>8)&0b111111111111100011111100)==0b011011110000000011100100) { + names="movi\0"; + j=((ic32>>11)&0xe0)|((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2d; args[1]=disasm_arg_imm64; + } else + if(((ic32>>8)&0b111111111111100011111100)==0b011011110000000011110100) { + names="fmov\0"; + j=((ic32>>11)&0xe0)|((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2d; args[1]=disasm_arg_F64; + } else + if(((ic32>>8)&0b111111110010000000001100)==0b011110000010000000000000) { + names="ldaddh\0ldclrh\0ldeorh\0ldseth\0ldsmaxh\0ldsminh\0ldumaxh\0lduminh\0swph\0?\0?\0?\0?\0?\0?\0?\0ldaddlh\0ldclrlh\0ldeorlh\0ldsetlh\0ldsmaxlh\0ldsminlh\0ldumaxlh\0lduminlh\0swplh\0?\0?\0?\0?\0?\0?\0?\0ldaddah\0ldclrah\0ldeorah\0ldsetah\0ldsmaxah\0ldsminah\0ldumaxah\0lduminah\0swpah\0?\0?\0?\0?\0?\0?\0?\0ldaddalh\0ldclralh\0ldeoralh\0ldsetalh\0ldsmaxalh\0ldsminalh\0ldumaxalh\0lduminalh\0swpalh\0"; + op=((ic32>>18)&0x30)|((ic32>>12)&0xf); d=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wd; args[1]=disasm_arg_Wt; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b111111111101111111111100)==0b011111100001000011001000) { + names="fmaxnmp\0"; + z=((ic32>>21)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_Vnz; + } else + if(((ic32>>8)&0b111111111110000011110100)==0b011111100100000000100100) { + names="fcmge\0facge\0"; + op=((ic32>>11)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Ht; args[1]=disasm_arg_Hn; args[2]=disasm_arg_Hm; + } else + if(((ic32>>8)&0b111111111010000011110100)==0b011111100010000011100100) { + names="fcmge\0facge\0"; + op=((ic32>>11)&0x1); z=((ic32>>22)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPn; args[2]=disasm_arg_FPm; + } else + if(((ic32>>8)&0b111111111110000011111100)==0b011111101100000000010100) { + names="fabd\0"; + m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Ht; args[1]=disasm_arg_Hn; args[2]=disasm_arg_Hm; + } else + if(((ic32>>8)&0b111111111110000011110100)==0b011111101100000000100100) { + names="fcmgt\0facgt\0"; + op=((ic32>>11)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Ht; args[1]=disasm_arg_Hn; args[2]=disasm_arg_Hm; + } else + if(((ic32>>8)&0b111111111010000011111100)==0b011111101010000011010100) { + names="fabd\0"; + z=((ic32>>22)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPn; args[2]=disasm_arg_FPm; + } else + if(((ic32>>8)&0b111111111010000011110100)==0b011111101010000011100100) { + names="fcmgt\0facgt\0"; + op=((ic32>>11)&0x1); z=((ic32>>22)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPn; args[2]=disasm_arg_FPm; + } else + if(((ic32>>8)&0b111111110010000011110100)==0b011111100000000010000100) { + names="sqrdmlah\0sqrdmlsh\0"; + op=((ic32>>11)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz2t; args[1]=disasm_arg_FPz2n; args[2]=disasm_arg_FPz2m; + } else + if(((ic32>>8)&0b111111110011111111001100)==0b011111100011000011001000) { + names="?\0faddp\0?\0fmaxp\0fminnmp\0?\0?\0fminp\0"; + op=((ic32>>21)&0x4)|((ic32>>12)&0x3); z=((ic32>>22)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_Vnz; + } else + if(((ic32>>8)&0b111111111100000011010100)==0b011111110100000011010000) { + names="sqrdmlah\0sqrdmlsh\0"; + op=((ic32>>13)&0x1); j=((ic32>>9)&0x4)|((ic32>>20)&0x3); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_FPz4t; args[1]=disasm_arg_FPz3n; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111000000011111100)==0b011111110000000001100100) { + names="sqshlu\0"; + j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Dt; args[1]=disasm_arg_Dn; args[2]=disasm_arg_shlshift; + } else + if(((ic32>>8)&0b111111111000000011111100)==0b011111110000000001110100) { + names="uqshl\0"; + j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPjt2; args[1]=disasm_arg_FPjn2; args[2]=disasm_arg_shlshift; + } else + if(((ic32>>8)&0b111111111100000011010100)==0b011111111000000011010000) { + names="sqrdmlah\0sqrdmlsh\0"; + op=((ic32>>13)&0x1); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2; + args[0]=disasm_arg_FPz4t; args[1]=disasm_arg_FPz3n; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b110111110011111110011100)==0b010011100010000100001000) { + names="?\0xtn2\0sqxtn2\0?\0?\0sqxtun2\0uqxtn2\0fcvtxn2\0"; + op=((ic32>>27)&0x4)|((ic32>>13)&0x3); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT3; + } else + if(((ic32>>8)&0b110111110010000011011100)==0b010011100010000000010000) { + names="saddw2\0ssubw2\0uaddw2\0usubw2\0"; + op=((ic32>>28)&0x2)|((ic32>>13)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_VtT3; args[1]=disasm_arg_VnT3; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b110111110010000011011100)==0b010011100010000001000000) { + names="addhn2\0subhn2\0raddhn2\0rsubhn2\0"; + op=((ic32>>28)&0x2)|((ic32>>13)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT3; args[2]=disasm_arg_VmT3; + } else + if(((ic32>>8)&0b110111110010000011111100)==0b010011100010000011100000) { + names="pmull2\0umull2\0"; + op=((ic32>>29)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_VtT4; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b110111110010000000001100)==0b010011100010000000000000) { + names="saddl2\0saddw2\0ssubl2\0ssubw2\0addhn2\0sabal2\0subhn2\0sabdl2\0smlal2\0sqdmlal2\0smlsl2\0sqdmlsl2\0?\0sqdmull2\0pmull2\0?\0uaddl2\0uaddw2\0usubl2\0usubw2\0raddhn2\0uabal2\0rsubhn2\0uabdl2\0umlal2\0?\0umlsl2\0?\0?\0?\0umull2\0"; + op=((ic32>>25)&0x10)|((ic32>>12)&0xf); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_VtT3; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b110111111100000000100100)==0b010011110100000000100000) { + names="smlal2\0sqdmlal2\0smlsl2\0sqdmlsl2\0smull2\0sqdmull2\0?\0?\0umlal2\0?\0umlsl2\0?\0umull2\0"; + op=((ic32>>26)&0x8)|((ic32>>13)&0x6)|((ic32>>12)&0x1); j=((ic32>>9)&0x4)|((ic32>>20)&0x3); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1;q=1; + args[0]=disasm_arg_Vtz; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b110111111000000011100100)==0b010011110000000010000100) { + names="?\0rshrn2\0sqshrn2\0sqrshrn2\0sqshrun2\0sqrshrun2\0uqshrn2\0uqrshrn2\0"; + op=((ic32>>27)&0x4)|((ic32>>11)&0x3); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_Vtj2; args[1]=disasm_arg_VnTa; args[2]=disasm_arg_shrshift; + } else + if(((ic32>>8)&0b110111111000000011111100)==0b010011110000000010100100) { + names="sshll2\0usshll2\0"; + op=((ic32>>29)&0x1); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + q=1; + args[0]=disasm_arg_Vtj2; args[1]=disasm_arg_VnTa; args[2]=disasm_arg_shlshift; + } else + if(((ic32>>8)&0b110111111100000000100100)==0b010011111000000000100000) { + names="smlal2\0sqdmlal2\0smlsl2\0sqdmlsl2\0smull2\0sqdmull2\0?\0?\0umlal2\0?\0umlsl2\0?\0umull2\0"; + op=((ic32>>26)&0x8)|((ic32>>13)&0x6)|((ic32>>12)&0x1); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2;q=1; + args[0]=disasm_arg_Vtz; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b110111111111111111001100)==0b010111101111100011001000) { + names="fcmgt\0fcmeq\0fcmlt\0?\0fcmge\0fcmle\0"; + op=((ic32>>27)&0x4)|((ic32>>12)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Ht; args[1]=disasm_arg_Hn; args[2]=disasm_arg_simd0; + } else + if(((ic32>>8)&0b110111111011111111001100)==0b010111101010000011001000) { + names="fcmgt\0fcmeq\0fcmlt\0?\0fcmge\0fcmle\0"; + op=((ic32>>27)&0x4)|((ic32>>12)&0x3); z=((ic32>>22)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPn; args[2]=disasm_arg_simd0; + } else + if(((ic32>>8)&0b110111110111111110001100)==0b010111100111100110001000) { + names="?\0?\0fcvtns\0fcvtms\0fcvtas\0scvtf\0?\0?\0?\0?\0fcvtps\0fcvtzs\0?\0frecpe\0?\0frecpx\0?\0?\0fcvtnu\0fcvtmu\0fcvtau\0ucvtf\0?\0?\0?\0?\0fcvtpu\0fcvtzu\0?\0frsqrte\0"; + op=((ic32>>25)&0x10)|((ic32>>20)&0x8)|((ic32>>12)&0x7); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Ht; args[1]=disasm_arg_Hn; + } else + if(((ic32>>8)&0b110111110011111111001100)==0b010111100010000010001000) { + names="cmgt\0cmeq\0cmlt\0abs\0cmge\0cmle\0?\0neg\0"; + op=((ic32>>27)&0x4)|((ic32>>12)&0x3); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz3t; args[1]=disasm_arg_FPz3n; args[2]=disasm_arg_simd0; + } else + if(((ic32>>8)&0b110111110011111100111100)==0b010111100010000000111000) { + names="suqadd\0sqabs\0abs\0?\0usqadd\0sqneg\0neg\0"; + op=((ic32>>27)&0x4)|((ic32>>14)&0x3); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz3t; args[1]=disasm_arg_FPz3n; + } else + if(((ic32>>8)&0b110111110011111110011100)==0b010111100010000100001000) { + names="?\0?\0sqxtn\0?\0?\0sqxtun\0uqxtn\0fcvtxn\0"; + op=((ic32>>27)&0x4)|((ic32>>13)&0x3); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz3t; args[1]=disasm_arg_FPz4n; + } else + if(((ic32>>8)&0b110111110011111110001100)==0b010111100010000110001000) { + names="?\0?\0fcvtns\0fcvtms\0fcvtas\0scvtf\0?\0?\0?\0?\0fcvtps\0fcvtzs\0?\0frecpe\0?\0frecpx\0?\0?\0fcvtnu\0fcvtmu\0fcvtau\0ucvtf\0?\0?\0?\0?\0fcvtpu\0fcvtzu\0?\0frsqrte\0"; + op=((ic32>>25)&0x10)|((ic32>>20)&0x8)|((ic32>>12)&0x7); z=((ic32>>22)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPn; + } else + if(((ic32>>8)&0b110111110010000000000100)==0b010111100010000000000100) { + names="?\0sqadd\0?\0?\0?\0sqsub\0cmgt\0cmge\0sshl\0sqshl\0srshl\0sqrshl\0?\0?\0?\0?\0add\0cmtst\0?\0?\0?\0?\0sqdmulh\0?\0?\0?\0?\0?\0?\0?\0?\0?\0?\0uqadd\0?\0?\0?\0uqsub\0cmhi\0cmhs\0ushl\0uqshl\0urshl\0uqrshl\0?\0?\0?\0?\0sub\0cmeq\0?\0?\0?\0?\0sqrdmulh\0"; + op=((ic32>>24)&0x20)|((ic32>>11)&0x1f); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz3t; args[1]=disasm_arg_FPz3n; args[2]=disasm_arg_FPz3m; + } else + if(((ic32>>8)&0b110111111100000000110100)==0b010111110000000000010000) { + names="fmla\0fmls\0fmul\0?\0?\0?\0fmulx\0"; + op=((ic32>>27)&0x4)|((ic32>>14)&0x3); j=((ic32>>9)&0x4)|((ic32>>20)&0x3); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Ht; args[1]=disasm_arg_Hn; args[2]=disasm_arg_VmHs; + } else + if(((ic32>>8)&0b110111111000000010001100)==0b010111110000000000000100) { + names="sshr\0ssra\0srshr\0srsra\0?\0shl\0?\0sqshl\0ushr\0usra\0urshr\0ursra\0sri\0sli\0sqshlu\0uqshl\0"; + op=((ic32>>26)&0x8)|((ic32>>12)&0x7); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Dt; args[1]=disasm_arg_Dn; args[2]=disasm_arg_shrshift; + } else + if(((ic32>>8)&0b110111111000000011100100)==0b010111110000000010000100) { + names="?\0?\0sqshrn\0sqrshrn\0sqshrun\0sqrshrun\0uqshrn\0uqrshrn\0"; + op=((ic32>>27)&0x4)|((ic32>>11)&0x3); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPjt; args[1]=disasm_arg_FPnj; args[2]=disasm_arg_shrshift; + } else + if(((ic32>>8)&0b110111111000000011111100)==0b010111110000000011100100) { + names="scvtf\0ucvtf\0"; + op=((ic32>>29)&0x1); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPjt2; args[1]=disasm_arg_FPjn2; args[2]=disasm_arg_shrshift; + } else + if(((ic32>>8)&0b110111111000000011111100)==0b010111110000000011111100) { + names="fcvtzs\0fcvtzu\0"; + op=((ic32>>29)&0x1); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPjt; args[1]=disasm_arg_FPjn2; args[2]=disasm_arg_shrshift; + } else + if(((ic32>>8)&0b110111111100000000110100)==0b010111111000000000010000) { + names="fmla\0fmls\0fmul\0sqrdmulh\0?\0?\0fmulx\0sqrdmlah\0"; + op=((ic32>>27)&0x4)|((ic32>>14)&0x3); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPn; args[2]=disasm_arg_VmTs2; + } else + if(((ic32>>8)&0b110111111110000000110100)==0b010111111100000000010000) { + names="fmla\0fmls\0fmul\0?\0?\0?\0fmulx\0"; + op=((ic32>>27)&0x4)|((ic32>>14)&0x3); j=((ic32>>11)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPn; args[2]=disasm_arg_VmTs2; + } else + if(((ic32>>8)&0b101111111010000001111100)==0b000010000010000001111100) { + names="casp\0caspl\0caspa\0caspal\0"; + op=((ic32>>21)&0x2)|((ic32>>15)&0x1); s=((ic32>>30)&0x1); d=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rd; args[1]=disasm_arg_Rd1; args[2]=disasm_arg_Rt; args[3]=disasm_arg_Rt1; args[4]=disasm_arg_offs; args[5]=disasm_arg_XnS; args[6]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111110011111101111100)==0b000010000001111101111100) { + names="?\0?\0ldxrb\0ldaxrb\0stllrb\0stlrb\0ldlarb\0ldarb\0?\0?\0ldxrh\0ldaxrh\0stllrh\0stlrh\0ldlarh\0ldarh\0"; + op=((ic32>>27)&0x8)|((ic32>>21)&0x6)|((ic32>>15)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111010000)==0b000011000000000000000000) { + names="st4\0st1\0ld4\0ld1\0"; + op=((ic32>>21)&0x2)|((ic32>>13)&0x1); q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_Vt4T; args[4]=disasm_arg_offs; args[5]=disasm_arg_XnS; args[6]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111110000)==0b000011000000000001110000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111010000)==0b000011000000000001000000) { + names="st3\0st1\0ld3\0ld1\0"; + op=((ic32>>21)&0x2)|((ic32>>13)&0x1); q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_offs; args[4]=disasm_arg_XnS; args[5]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111010000)==0b000011000000000010000000) { + names="st2\0st1\0ld2\0ld1\0"; + op=((ic32>>21)&0x2)|((ic32>>13)&0x1); q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111010000)==0b000011001001111100000000) { + names="st4\0st1\0ld4\0ld1\0"; + op=((ic32>>21)&0x2)|((ic32>>13)&0x1); q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_Vt4T; args[4]=disasm_arg_offs; args[5]=disasm_arg_XnS; args[6]=disasm_arg_offe; args[7]=disasm_arg_Qi; + } else + if(((ic32>>8)&0b101111111011111111110000)==0b000011001001111101110000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Qi1; + } else + if(((ic32>>8)&0b101111111011111111010000)==0b000011001001111101000000) { + names="st3\0st1\0ld3\0ld1\0"; + op=((ic32>>21)&0x2)|((ic32>>13)&0x1); q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_offs; args[4]=disasm_arg_XnS; args[5]=disasm_arg_offe; args[6]=disasm_arg_Qi3; + } else + if(((ic32>>8)&0b101111111011111111010000)==0b000011001001111110000000) { + names="st2\0st1\0ld2\0ld1\0"; + op=((ic32>>21)&0x2)|((ic32>>13)&0x1); q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; args[5]=disasm_arg_Qi2; + } else + if(((ic32>>8)&0b101111111010000011010000)==0b000011001000000000000000) { + names="st4\0st1\0ld4\0ld1\0"; + op=((ic32>>21)&0x2)|((ic32>>13)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_Vt4T; args[4]=disasm_arg_offs; args[5]=disasm_arg_XnS; args[6]=disasm_arg_offe; args[7]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011110000)==0b000011001000000001110000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011010000)==0b000011001000000001000000) { + names="st3\0st1\0ld3\0ld1\0"; + op=((ic32>>21)&0x2)|((ic32>>13)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_offs; args[4]=disasm_arg_XnS; args[5]=disasm_arg_offe; args[6]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011010000)==0b000011001000000010000000) { + names="st2\0st1\0ld2\0ld1\0"; + op=((ic32>>21)&0x2)|((ic32>>13)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; args[5]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111111111111110000)==0b000011010100000011000000) { + names="ld1r\0"; + q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111111111111110000)==0b000011010100000011100000) { + names="ld3r\0"; + q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_offs; args[4]=disasm_arg_XnS; args[5]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111111111111110000)==0b000011010110000011000000) { + names="ld2r\0"; + q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111111111111110000)==0b000011010110000011100000) { + names="ld4r\0"; + q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_Vt4T; args[4]=disasm_arg_offs; args[5]=disasm_arg_XnS; args[6]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011010000000000000000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtB; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011010000000000100000) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3B; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011010000000001000000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011010000000001100000) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3H; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111111100)==0b000011010000000010000100) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtD; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111101100)==0b000011010000000010000000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtS; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111111100)==0b000011010000000010100100) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3D; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111101100)==0b000011010000000010100000) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3S; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011010010000000000000) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2B; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011010010000000100000) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4B; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011010010000001000000) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2H; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011010010000001100000) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4H; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111111100)==0b000011010010000010000100) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2D; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111101100)==0b000011010010000010000000) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2S; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111111100)==0b000011010010000010100100) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4D; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111011111111101100)==0b000011010010000010100000) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4S; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111111111111110000)==0b000011011101111111000000) { + names="ld1r\0"; + q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_z; + } else + if(((ic32>>8)&0b101111111111111111110000)==0b000011011101111111100000) { + names="ld3r\0"; + q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_offs; args[4]=disasm_arg_XnS; args[5]=disasm_arg_offe; args[6]=disasm_arg_z3; + } else + if(((ic32>>8)&0b101111111110000011110000)==0b000011011100000011000000) { + names="ld1r\0"; + q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111110000011110000)==0b000011011100000011100000) { + names="ld3r\0"; + q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_offs; args[4]=disasm_arg_XnS; args[5]=disasm_arg_offe; args[6]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111111111111110000)==0b000011011111111111000000) { + names="ld2r\0"; + q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; args[5]=disasm_arg_z2; + } else + if(((ic32>>8)&0b101111111111111111110000)==0b000011011111111111100000) { + names="ld4r\0"; + q=((ic32>>30)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_Vt4T; args[4]=disasm_arg_offs; args[5]=disasm_arg_XnS; args[6]=disasm_arg_offe; args[7]=disasm_arg_z4; + } else + if(((ic32>>8)&0b101111111110000011110000)==0b000011011110000011000000) { + names="ld2r\0"; + q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; args[5]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111110000011110000)==0b000011011110000011100000) { + names="ld4r\0"; + q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vt2T; args[2]=disasm_arg_Vt3T; args[3]=disasm_arg_Vt4T; args[4]=disasm_arg_offs; args[5]=disasm_arg_XnS; args[6]=disasm_arg_offe; args[7]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011011001111100000000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtB; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i1; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011011001111100100000) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3B; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i3; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011011001111101000000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i2; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011011001111101100000) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3H; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i6; + } else + if(((ic32>>8)&0b101111111011111111111100)==0b000011011001111110000100) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtD; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i8; + } else + if(((ic32>>8)&0b101111111011111111101100)==0b000011011001111110000000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtS; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i4; + } else + if(((ic32>>8)&0b101111111011111111111100)==0b000011011001111110100100) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3D; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i24; + } else + if(((ic32>>8)&0b101111111011111111101100)==0b000011011001111110100000) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3S; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i12; + } else + if(((ic32>>8)&0b101111111010000011100000)==0b000011011000000000000000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtB; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011100000)==0b000011011000000000100000) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3B; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011100000)==0b000011011000000001000000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011100000)==0b000011011000000001100000) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3H; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011111100)==0b000011011000000010000100) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtD; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011101100)==0b000011011000000010000000) { + names="st1\0ld1\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtS; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011111100)==0b000011011000000010100100) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3D; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011101100)==0b000011011000000010100000) { + names="st3\0ld3\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt3S; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011011011111100000000) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2B; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i2; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011011011111100100000) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4B; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i4; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011011011111101000000) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2H; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i4; + } else + if(((ic32>>8)&0b101111111011111111100000)==0b000011011011111101100000) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4H; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i8; + } else + if(((ic32>>8)&0b101111111011111111111100)==0b000011011011111110000100) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2D; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i16; + } else + if(((ic32>>8)&0b101111111011111111101100)==0b000011011011111110000000) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2S; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i8; + } else + if(((ic32>>8)&0b101111111011111111111100)==0b000011011011111110100100) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4D; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i32; + } else + if(((ic32>>8)&0b101111111011111111101100)==0b000011011011111110100000) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4S; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i16; + } else + if(((ic32>>8)&0b101111111010000011100000)==0b000011011010000000000000) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2B; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011100000)==0b000011011010000000100000) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4B; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011100000)==0b000011011010000001000000) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2H; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011100000)==0b000011011010000001100000) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); z=((ic32>>10)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4H; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011111100)==0b000011011010000010000100) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2D; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011101100)==0b000011011010000010000000) { + names="st2\0ld2\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2S; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011111100)==0b000011011010000010100100) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4D; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111010000011101100)==0b000011011010000010100000) { + names="st4\0ld4\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); s=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4S; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b101111111110000011111100)==0b000011100000000000000100) { + names="dup\0"; + q=((ic32>>30)&0x1); j=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtjq; args[1]=disasm_arg_Vnj; args[2]=disasm_arg_offs; args[3]=disasm_arg_FPidx; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111110000011101100)==0b000011100000000000000000) { + names="tbl\0tbx\0"; + op=((ic32>>12)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vn116b; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b101111111110000011101100)==0b000011100000000000100000) { + names="tbl\0tbx\0"; + op=((ic32>>12)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vn216b; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b101111111110000011101100)==0b000011100000000000101100) { + names="smov\0umov\0"; + op=((ic32>>12)&0x1); s=((ic32>>30)&0x1); j=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Vnj; args[2]=disasm_arg_offs; args[3]=disasm_arg_FPidx; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111110000011101100)==0b000011100000000001000000) { + names="tbl\0tbx\0"; + op=((ic32>>12)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vn316b; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b101111111110000011101100)==0b000011100000000001100000) { + names="tbl\0tbx\0"; + op=((ic32>>12)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vn416b; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b101111111110000011111100)==0b000011100100000000011100) { + names="fmulx\0"; + q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH1; args[1]=disasm_arg_VnH1; args[2]=disasm_arg_VmH1; + } else + if(((ic32>>8)&0b101111111110000011111100)==0b000011100100000000100100) { + names="fcmeq\0"; + q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH1; args[1]=disasm_arg_VnH1; args[2]=disasm_arg_VmH1; + } else + if(((ic32>>8)&0b101111111111111111101100)==0b000011100111100110001000) { + names="frintn\0frintm\0"; + op=((ic32>>12)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b101111111111111111111100)==0b000011100111100111111000) { + names="fabs\0"; + q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b101111111010000011111100)==0b000011100010000000011100) { + names="fmulx\0"; + q=((ic32>>30)&0x1); z=((ic32>>22)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtzq; args[1]=disasm_arg_Vnzq; args[2]=disasm_arg_Vmzq; + } else + if(((ic32>>8)&0b101111111111111111101100)==0b000011101111100110001000) { + names="frintp\0frintz\0"; + op=((ic32>>12)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b101111110111111111001100)==0b000011100011000011001000) { + names="fmaxnmv\0?\0?\0fmaxv\0fminnmv\0?\0?\0fminv\0"; + op=((ic32>>21)&0x4)|((ic32>>12)&0x3); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_Ht; args[1]=disasm_arg_Vnzq2; + } else + if(((ic32>>8)&0b101111110110000011111100)==0b000011100100000000111100) { + names="frecps\0frsqrts\0"; + op=((ic32>>23)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH1; args[1]=disasm_arg_VnH1; args[2]=disasm_arg_VmH1; + } else + if(((ic32>>8)&0b101111110000000010000000)==0b000011100000000000000000) { + names="?\0?\0?\0?\0?\0?\0uzp1\0?\0?\0?\0trn1\0?\0?\0?\0zip1\0?\0?\0?\0?\0?\0?\0?\0uzp2\0?\0?\0?\0trn2\0?\0?\0?\0zip2\0?\0?\0shadd\0?\0sqadd\0?\0srhadd\0?\0?\0?\0?\0?\0sqsub\0?\0cmgt\0?\0cmge\0?\0sshl\0?\0sqshl\0?\0srshl\0?\0sqrshl\0?\0smax\0?\0smin\0?\0sabd\0?\0saba\0"; + op=((ic32>>16)&0x20)|((ic32>>10)&0x1f); q=((ic32>>30)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b101111111111100011111100)==0b000011110000000011100100) { + names="movi\0"; + q=((ic32>>30)&0x1); j=((ic32>>11)&0xe0)|((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_imm8; + } else + if(((ic32>>8)&0b101111111111100011111100)==0b000011110000000011110100) { + names="fmov\0"; + q=((ic32>>30)&0x1); j=((ic32>>11)&0xe0)|((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_F32; + } else + if(((ic32>>8)&0b101111111111100011111100)==0b000011110000000011111100) { + names="fmov\0"; + q=((ic32>>30)&0x1); j=((ic32>>11)&0xe0)|((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_F16; + } else + if(((ic32>>8)&0b101111111100000010100100)==0b000011110100000010000000) { + names="mul\0?\0sqdmulh\0sqrdmulh\0"; + op=((ic32>>13)&0x2)|((ic32>>12)&0x1); j=((ic32>>9)&0x4)|((ic32>>20)&0x3); q=((ic32>>30)&0x1); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b101111111000000011001100)==0b000011110000000000000100) { + names="sshr\0ssra\0srshr\0srsra\0"; + op=((ic32>>12)&0x3); q=((ic32>>30)&0x1); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtj2; args[1]=disasm_arg_Vnj2; args[2]=disasm_arg_shrshift; + } else + if(((ic32>>8)&0b101111111000000011111100)==0b000011110000000011100100) { + names="scvtf\0"; + q=((ic32>>30)&0x1); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtj2; args[1]=disasm_arg_Vnj2; args[2]=disasm_arg_shrshift; + } else + if(((ic32>>8)&0b101111111000000011111100)==0b000011110000000011111100) { + names="fcvtzs\0"; + q=((ic32>>30)&0x1); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtj2; args[1]=disasm_arg_Vnj2; args[2]=disasm_arg_shrshift; + } else + if(((ic32>>8)&0b101111111100000010100100)==0b000011111000000010000000) { + names="mul\0fmul\0sqdmulh\0sqrdmulh\0"; + op=((ic32>>13)&0x2)|((ic32>>12)&0x1); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>24)&0b10111111)==0b00011000) { + names="ldr\0"; + s=((ic32>>30)&0x1); i=((ic32>>23)&1?(-1<<19):0)|((ic32>>5)&0x7ffff); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_labeli4; + } else + if(((ic32>>8)&0b101111111110000011111100)==0b000111100000000000001100) { + names="dup\0"; + q=((ic32>>30)&0x1); j=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + s=q; + args[0]=disasm_arg_Vtjq; args[1]=disasm_arg_Rn; + } else + if(((ic32>>8)&0b101111111110000010000100)==0b001011100000000000000000) { + names="ext\0"; + q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); i=((ic32>>14)&1?(-1<<4):0)|((ic32>>11)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; args[3]=disasm_arg_i; + } else + if(((ic32>>8)&0b101111111110000011110100)==0b001011100100000000100100) { + names="fcmge\0facge\0"; + op=((ic32>>11)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH1; args[1]=disasm_arg_VnH1; args[2]=disasm_arg_VmH1; + } else + if(((ic32>>8)&0b101111111111111111111100)==0b001011100111100110011000) { + names="frintx\0"; + q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b101111111011111111111100)==0b001011100010000001011000) { + names="not\0rbit\0"; + op=((ic32>>22)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b101111111110000011111100)==0b001011101100000000010100) { + names="fabd\0"; + q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH1; args[1]=disasm_arg_VnH1; args[2]=disasm_arg_VmH1; + } else + if(((ic32>>8)&0b101111111110000011110100)==0b001011101100000000100100) { + names="fcmgt\0facgt\0"; + op=((ic32>>11)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH1; args[1]=disasm_arg_VnH1; args[2]=disasm_arg_VmH1; + } else + if(((ic32>>8)&0b101111111111111111111100)==0b001011101111100011111000) { + names="fneg\0"; + q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b101111111111111111101100)==0b001011101111100110001000) { + names="frinta\0frinti\0"; + op=((ic32>>12)&0x1); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b101111111111111111111100)==0b001011101111100111111000) { + names="fsqrt\0"; + q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b101111110010000000000100)==0b001011100010000000000100) { + names="uhadd\0uqadd\0urhadd\0?\0uhsub\0uqsub\0cmhi\0cmhs\0ushl\0uqshl\0urshl\0uqrshl\0umax\0umin\0uabd\0uaba\0sub\0cmeq\0mls\0pmul\0umaxp\0uminp\0cqrdmulh\0"; + op=((ic32>>11)&0x1f); q=((ic32>>30)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b101111111100000011010100)==0b001011110100000011010000) { + names="sqrdmlah\0sqrdmlsh\0"; + op=((ic32>>13)&0x1); j=((ic32>>9)&0x4)|((ic32>>20)&0x3); q=((ic32>>30)&0x1); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_Vtz; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b101111111000000011111100)==0b001011110000000011111100) { + names="fcvtzu\0"; + q=((ic32>>30)&0x1); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtj2; args[1]=disasm_arg_Vnj2; args[2]=disasm_arg_shrshift; + } else + if(((ic32>>8)&0b101111111000000000001100)==0b001011110000000000000100) { + names="ushr\0usra\0urshr\0ursra\0sri\0sli\0sqshlu\0uqshl\0?\0?\0?\0?\0?\0?\0ucvtf\0"; + op=((ic32>>12)&0xf); q=((ic32>>30)&0x1); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtj2; args[1]=disasm_arg_Vnj2; args[2]=disasm_arg_shrshift; + } else + if(((ic32>>8)&0b101111111100000011010100)==0b001011111000000011010000) { + names="sqrdmlah\0sqrdmlsh\0"; + op=((ic32>>13)&0x1); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=2; + args[0]=disasm_arg_Vtz; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b101111110000000010110100)==0b001011110000000000000000) { + names="mla\0mls\0"; + op=((ic32>>14)&0x1); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); q=((ic32>>30)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b101111111010000000001100)==0b001110000000000000000100) { + names="strb\0ldrb\0strh\0ldrh\0"; + op=((ic32>>29)&0x2)|((ic32>>22)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i_opt; + } else + if(((ic32>>8)&0b101111111010000000000100)==0b001110000000000000000100) { + names="strb\0ldrb\0strh\0ldrh\0"; + op=((ic32>>29)&0x2)|((ic32>>22)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); p=((ic32>>11)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_i_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111010000000001100)==0b001110000010000000001000) { + names="strb\0ldrb\0strh\0ldrh\0"; + op=((ic32>>29)&0x2)|((ic32>>22)&0x1); m=((ic32>>16)&0x1f); o=((ic32>>13)&0x7); j=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_Rom; args[4]=disasm_arg_amountj; args[5]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111010000000001100)==0b001110001000000000000100) { + names="ldrsb\0ldrsh\0"; + op=((ic32>>30)&0x1); s=((ic32>>22)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_nRt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i_opt; + } else + if(((ic32>>8)&0b101111111010000000000100)==0b001110001000000000000000) { + names="ldursb\0?\0ldursh\0ldtrsh\0"; + op=((ic32>>29)&0x2)|((ic32>>11)&0x1); s=((ic32>>22)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_nRt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_i_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111010000000000100)==0b001110001000000000000100) { + names="ldrsb\0ldrsh\0"; + op=((ic32>>30)&0x1); s=((ic32>>22)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); p=((ic32>>11)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_nRt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_i_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111010000000001100)==0b001110001010000000001000) { + names="ldrsb\0ldrsh\0"; + op=((ic32>>30)&0x1); s=((ic32>>22)&0x1); m=((ic32>>16)&0x1f); o=((ic32>>13)&0x7); j=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_nRt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_Rom; args[4]=disasm_arg_amountj; args[5]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111110010000000000100)==0b001110000000000000000000) { + names="sturb\0sttrb\0ldurb\0ldtrb\0?\0ldtrsb\0?\0ldtrsb\0sturh\0sttrh\0ldurh\0ldtrh\0"; + op=((ic32>>27)&0x8)|((ic32>>21)&0x6)|((ic32>>11)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_i_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>16)&0b1011111110000000)==0b0011100100000000) { + names="strb\0ldrb\0strh\0ldrh\0"; + op=((ic32>>29)&0x2)|((ic32>>22)&0x1); j=((ic32>>10)&0xfff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_j_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>16)&0b1011111110000000)==0b0011100110000000) { + names="ldrsb\0ldrsh\0"; + op=((ic32>>30)&0x1); s=((ic32>>22)&0x1); j=((ic32>>10)&0xfff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_nRt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_j_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b100111111111111111001100)==0b000011101111100011001000) { + names="fcmgt\0fcmeq\0fcmlt\0?\0fcmge\0fcmle\0?\0fneg\0"; + op=((ic32>>27)&0x4)|((ic32>>12)&0x3); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH1; args[1]=disasm_arg_VnH1; args[2]=disasm_arg_simd0; + } else + if(((ic32>>8)&0b100111111011111111001100)==0b000011101010000011001000) { + names="fcmgt\0fcmeq\0fcmlt\0?\0fcmge\0fcmle\0?\0fneg\0"; + op=((ic32>>27)&0x4)|((ic32>>12)&0x3); q=((ic32>>30)&0x1); z=((ic32>>22)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtzq; args[1]=disasm_arg_Vnzq; args[2]=disasm_arg_simd0; + } else + if(((ic32>>8)&0b100111110110000011000100)==0b000011100100000000000100) { + names="fmaxnm\0fmla\0fadd\0fmulx\0fcmeq\0?\0fmax\0frecps\0fminnm\0fmls\0fsub\0?\0?\0?\0fmin\0frsqrts\0fmaxnmp\0?\0faddp\0fmul\0fcmge\0facge\0fmaxp\0fdiv\0fminnmp\0?\0fabd\0?\0fcmgt\0facgt\0fminp\0"; + op=((ic32>>25)&0x10)|((ic32>>20)&0x8)|((ic32>>11)&0x7); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b100111110111111110001100)==0b000011100111100110001000) { + names="frintn\0frintm\0fcvtns\0fcvtms\0fcvtas\0scvtf\0?\0fabs\0frintp\0frintz\0fcvtps\0fcvtzs\0?\0frecpe\0?\0frecpx\0?\0frintx\0fcvtnu\0fcvtmu\0fcvtau\0ucvtf\0?\0?\0frinta\0frinti\0fcvtpu\0fcvtzu\0?\0frsqrte\0?\0fsqrt\0"; + op=((ic32>>25)&0x10)|((ic32>>20)&0x8)|((ic32>>12)&0x7); q=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH1; args[1]=disasm_arg_VnH1; + } else + if(((ic32>>8)&0b100111110010000011111100)==0b000011100000000010010100) { + names="sdot\0udot\0"; + op=((ic32>>29)&0x1); q=((ic32>>30)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_Vnzq; args[2]=disasm_arg_Vmzq; + } else + if(((ic32>>8)&0b100111110011111110111100)==0b000011100010000000101000) { + names="saddlp\0sadalp\0uaddlp\0uadalp\0"; + op=((ic32>>28)&0x2)|((ic32>>14)&0x1); q=((ic32>>30)&0x1); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtzq2; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b100111110011111111001100)==0b000011100010000010001000) { + names="cmgt\0cmeq\0cmlt\0abs\0cmge\0cmle\0?\0neg\0"; + op=((ic32>>27)&0x4)|((ic32>>12)&0x3); q=((ic32>>30)&0x1); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_simd0; + } else + if(((ic32>>8)&0b100111110011111100001100)==0b000011100010000000001000) { + names="rev64\0rev16\0saddlp\0suqadd\0cls\0cnt\0sadalp\0sqabs\0cmgt\0cmeq\0cmlt\0abs\0?\0?\0?\0?\0rev32\0?\0uaddlp\0usqadd\0clz\0?\0uadalp\0sqneg\0cmge\0cmle\0?\0neg\0"; + op=((ic32>>25)&0x10)|((ic32>>12)&0xf); q=((ic32>>30)&0x1); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b100111110011111010001100)==0b000011100010000010001000) { + names="?\0?\0?\0?\0?\0?\0?\0?\0frintn\0frintm\0fcvtns\0fcvtms\0fcvtas\0scvtf\0?\0fabs\0?\0?\0?\0?\0fcmgt\0fcmeq\0fcmlt\0?\0frintp\0frintz\0fcvtps\0fcvtzs\0urecpe\0frecpe\0?\0frecpx\0?\0?\0?\0?\0?\0?\0?\0?\0?\0frintx\0fcvtnu\0fcvtmu\0fcvtau\0ucvtf\0?\0?\0?\0?\0?\0?\0fcmge\0fcmle\0?\0fneg\0frinta\0frinti\0fcvtpu\0fcvtzu\0?\0frsqrte\0?\0fsqrt\0"; + op=((ic32>>24)&0x20)|((ic32>>19)&0x10)|((ic32>>13)&0x8)|((ic32>>12)&0x7); q=((ic32>>30)&0x1); z=((ic32>>22)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtzq; args[1]=disasm_arg_Vnzq; + } else + if(((ic32>>8)&0b100111110011111111111100)==0b000011100011000000111000) { + names="saddlv\0uaddlv\0"; + op=((ic32>>29)&0x1); q=((ic32>>30)&0x1); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz4t; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b100111110011111011101100)==0b000011100011000010101000) { + names="smaxv\0?\0sminv\0addv\0umaxv\0?\0uminv\0"; + op=((ic32>>27)&0x4)|((ic32>>15)&0x2)|((ic32>>12)&0x1); q=((ic32>>30)&0x1); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz3t; args[1]=disasm_arg_VnT; + } else + if(((ic32>>8)&0b100111110010000011111100)==0b000011100010000000011100) { + names="and\0bic\0orr\0orn\0eor\0bsl\0bit\0bif\0"; + op=((ic32>>27)&0x4)|((ic32>>22)&0x3); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b100111110010000011000100)==0b000011100010000011000100) { + names="fmaxnm\0fmla\0fadd\0?\0fcmeq\0?\0fmax\0frecps\0fminnm\0fmls\0fsub\0?\0?\0?\0fmin\0frsqrts\0fmaxnmp\0?\0faddp\0fmul\0fcmge\0facge\0fmaxp\0fdiv\0fminnmp\0?\0fabd\0?\0fcmgt\0facgt\0fminp\0"; + op=((ic32>>25)&0x10)|((ic32>>20)&0x8)|((ic32>>11)&0x7); q=((ic32>>30)&0x1); z=((ic32>>22)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtzq; args[1]=disasm_arg_Vnzq; args[2]=disasm_arg_Vmzq; + } else + if(((ic32>>8)&0b100111110000000011000100)==0b000011100000000010000100) { + names="?\0?\0sdot\0?\0?\0?\0?\0?\0add\0cmtst\0mla\0mul\0smaxp\0sminp\0sqdmulh\0addp\0sqrdmlah\0sqrdmlsh\0udot\0?\0?\0?\0?\0?\0sub\0cmeq\0mls\0pmul\0umaxp\0uminp\0cqrdmulh\0"; + op=((ic32>>25)&0x10)|((ic32>>18)&0x8)|((ic32>>11)&0x7); q=((ic32>>30)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtT; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmT; + } else + if(((ic32>>8)&0b100111111111100010001100)==0b000011110000000000000100) { + names="movi\0orr\0mvni\0bic\0"; + op=((ic32>>28)&0x2)|((ic32>>12)&0x1); q=((ic32>>30)&0x1); j=((ic32>>11)&0xe0)|((ic32>>5)&0x1f); k=((ic32>>13)&0x3); t=((ic32>>0)&0x1f); + z=2; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_imm8; args[2]=disasm_arg_amountk_opt; + } else + if(((ic32>>8)&0b100111111111100011001100)==0b000011110000000010000100) { + names="movi\0orr\0mvni\0bic\0"; + op=((ic32>>28)&0x2)|((ic32>>12)&0x1); q=((ic32>>30)&0x1); j=((ic32>>11)&0xe0)|((ic32>>5)&0x1f); k=((ic32>>13)&0x1); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_imm8; args[2]=disasm_arg_amountk_opt; + } else + if(((ic32>>8)&0b100111111111100011101100)==0b000011110000000011000100) { + names="movi\0mvni\0"; + op=((ic32>>29)&0x1); q=((ic32>>30)&0x1); j=((ic32>>11)&0xe0)|((ic32>>5)&0x1f); k=((ic32>>12)&0x1); t=((ic32>>0)&0x1f); + z=2; + args[0]=disasm_arg_VtT; args[1]=disasm_arg_imm8; args[2]=disasm_arg_amountk2_opt; + } else + if(((ic32>>8)&0b100111111100000000110100)==0b000011110000000000010000) { + names="fmla\0fmls\0fmul\0?\0?\0?\0fmulx\0"; + op=((ic32>>27)&0x4)|((ic32>>14)&0x3); j=((ic32>>9)&0x4)|((ic32>>20)&0x3); q=((ic32>>30)&0x1); m=((ic32>>16)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_VtH1; args[1]=disasm_arg_VnH1; args[2]=disasm_arg_VmHs; + } else + if(((ic32>>8)&0b100111111000000011001100)==0b000011110000000001000100) { + names="?\0shl\0?\0sqshl\0sri\0sli\0sqshlu\0uqshl\0"; + op=((ic32>>27)&0x4)|((ic32>>12)&0x3); q=((ic32>>30)&0x1); j=((ic32>>16)&0x7f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vtj2; args[1]=disasm_arg_Vnj2; args[2]=disasm_arg_shlshift; + } else + if(((ic32>>8)&0b100111111100000011110100)==0b000011111000000011100000) { + names="sdot\0udot\0"; + op=((ic32>>29)&0x1); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_Vtzq; args[1]=disasm_arg_VnT; args[2]=disasm_arg_VmTs4b; + } else + if(((ic32>>8)&0b100111111100000000110100)==0b000011111000000000010000) { + names="fmla\0fmls\0fmul\0sqrdmulh\0?\0?\0fmulx\0sqrdmlah\0"; + op=((ic32>>27)&0x4)|((ic32>>14)&0x3); j=((ic32>>10)&0x2)|((ic32>>21)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_Vtzq; args[1]=disasm_arg_Vnzq; args[2]=disasm_arg_VmTs2; + } else + if(((ic32>>8)&0b100111111110000000110100)==0b000011111100000000010000) { + names="fmla\0fmls\0fmul\0?\0?\0?\0fmulx\0"; + op=((ic32>>27)&0x4)|((ic32>>14)&0x3); j=((ic32>>11)&0x1); q=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=1; + args[0]=disasm_arg_Vtzq; args[1]=disasm_arg_Vnzq; args[2]=disasm_arg_VmTs2; + } else + if(((ic32>>8)&0b111111111110000001111100)==0b100010000000000001111100) { + names="stxr\0stlxr\0"; + op=((ic32>>15)&0x1); d=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wd; args[1]=disasm_arg_Wt; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; + } else + if(((ic32>>24)&0b11111111)==0b10011000) { + names="ldrsw\0"; + i=((ic32>>23)&1?(-1<<19):0)|((ic32>>5)&0x7ffff); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_labeli4; + } else + if(((ic32>>8)&0b111111110110000001111100)==0b100110110010000001111100) { + names="smull\0smnegl\0umull\0umnegl\0"; + op=((ic32>>22)&0x2)|((ic32>>15)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_Wn; args[2]=disasm_arg_Wm; + } else + if(((ic32>>16)&0b1111111101100000)==0b1001101100100000) { + names="smaddl\0smsubl\0umaddl\0umsubl\0"; + op=((ic32>>22)&0x2)|((ic32>>15)&0x1); m=((ic32>>16)&0x1f); d=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_Wn; args[2]=disasm_arg_Wm; args[3]=disasm_arg_Xd; + } else + if(((ic32>>8)&0b111111110110000011111100)==0b100110110100000001111100) { + names="smulh\0umulh\0"; + op=((ic32>>23)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_Xn; args[2]=disasm_arg_Xm; + } else + if(((ic32>>8)&0b111111111110000000001100)==0b101110001000000000000100) { + names="ldrsw\0"; + i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i_opt; + } else + if(((ic32>>8)&0b111111111110000000000100)==0b101110001000000000000100) { + names="ldrsw\0"; + i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); p=((ic32>>11)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_i_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b111111111110000000001100)==0b101110001010000000001000) { + names="ldrsw\0"; + m=((ic32>>16)&0x1f); o=((ic32>>13)&0x7); j=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_Rom; args[4]=disasm_arg_amountj2; args[5]=disasm_arg_offe; + } else + if(((ic32>>16)&0b1111111111000000)==0b1011100110000000) { + names="ldrsw\0"; + j=((ic32>>10)&0xfff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_j_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b111111111100000010000000)==0b110011100000000000000000) { + names="eor3\0bcax\0"; + op=((ic32>>21)&0x1); m=((ic32>>16)&0x1f); d=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt16b; args[1]=disasm_arg_Vn16b; args[2]=disasm_arg_Vm16b; args[3]=disasm_arg_Vd16b; + } else + if(((ic32>>8)&0b111111111110000010000000)==0b110011100100000000000000) { + names="sm3ss1\0"; + m=((ic32>>16)&0x1f); d=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4s; args[1]=disasm_arg_Vn4s; args[2]=disasm_arg_Vm4s; args[3]=disasm_arg_Vd4s; + } else + if(((ic32>>8)&0b111111111110000011000000)==0b110011100100000010000000) { + names="sm3tt1a\0sm3tt1b\0sm3tt2a\0sm3tt2b\0"; + op=((ic32>>10)&0x3); m=((ic32>>16)&0x1f); j=((ic32>>12)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + z=0; + args[0]=disasm_arg_Vt4s; args[1]=disasm_arg_Vn4s; args[2]=disasm_arg_VmTs; + } else + if(((ic32>>8)&0b111111111110000011111000)==0b110011100110000010000000) { + names="sha512h\0sha512h2\0"; + op=((ic32>>10)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Qt; args[1]=disasm_arg_Qn; args[2]=disasm_arg_Vm2d; + } else + if(((ic32>>8)&0b111111111110000011111000)==0b110011100110000010001000) { + names="sha512su1\0rax1\0"; + op=((ic32>>10)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2d; args[1]=disasm_arg_Vn2d; args[2]=disasm_arg_Vm2d; + } else + if(((ic32>>8)&0b111111111110000011110000)==0b110011100110000011000000) { + names="sm3partw1\0sm3partw2\0sm4ekey\0"; + op=((ic32>>10)&0x3); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4s; args[1]=disasm_arg_Vn4s; args[2]=disasm_arg_Vm4s; + } else + if(((ic32>>8)&0b111111111111111111111100)==0b110011101100000010000000) { + names="sha512su0\0"; + n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt2d; args[1]=disasm_arg_Vn2d; + } else + if(((ic32>>8)&0b111111111111111111111100)==0b110011101100000010000100) { + names="sm4e\0"; + n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt4s; args[1]=disasm_arg_Vn4s; + } else + if(((ic32>>16)&0b1111111111000000)==0b1101010000000000) { + names="?\0svc\0hvc\0smc\0brk\0"; + op=((ic32>>19)&0x4)|((ic32>>0)&0x3); i=((ic32>>20)&1?(-1<<16):0)|((ic32>>5)&0xffff); + args[0]=disasm_arg_i; + } else + if((ic32&0b11111111111000000000000000000011)==0b11010100010000000000000000000000) { + names="hlt\0"; + } else + if(((ic32>>16)&0b1111111111100000)==0b1101010010100000) { + names="?\0dcsp1\0dcps2\0dcps3\0"; + op=((ic32>>0)&0x3); i=((ic32>>20)&1?(-1<<16):0)|((ic32>>5)&0xffff); + args[0]=disasm_arg_i_opt; + } else + if((ic32&0b11111111111111111111110100011111)==0b11010101000000110010000000011111) { + names="nop\0yield\0wfe\0wfi\0sev\0sevl\0?\0?\0esb\0psc\0"; + op=((ic32>>6)&0x8)|((ic32>>5)&0x7); + } else + if((ic32&0b11111111111111111111000011111111)==0b11010101000000110011000001011111) { + names="clrex\0"; + i=((ic32>>11)&1?(-1<<4):0)|((ic32>>8)&0xf); + args[0]=disasm_arg_i_opt; + } else + if((ic32&0b11111111111111111111000010011111)==0b11010101000000110011000010011111) { + names="dsb\0dmb\0?\0isb\0"; + op=((ic32>>5)&0x3); j=((ic32>>8)&0xf); + args[0]=disasm_arg_sh; + } else + if((ic32&0b11111111111110001111000000011111)==0b11010101000000000100000000011111) { + names="msr\0"; + i=((ic32>>11)&1?(-1<<4):0)|((ic32>>8)&0xf); p=((ic32>>5)&0x7); + args[0]=disasm_arg_pstate; args[1]=disasm_arg_i; + } else + if((ic32&0b11111111111111111111111110000000)==0b11010101000010000111011000000000) { + names="dc\0"; + d=((ic32>>5)&0x3); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_dc0; args[1]=disasm_arg_Xt; + } else + if((ic32&0b11111111111111111111111110000000)==0b11010101000010000111100000000000) { + names="at\0"; + a=((ic32>>5)&0x3); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_a0; args[1]=disasm_arg_Xt; + } else + if(((ic32>>8)&0b111111111111111111111111)==0b110101010000100001111001) { + names="at\0"; + a=((ic32>>5)&0x7); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_a1; args[1]=disasm_arg_Xt; + } else + if((ic32&0b11111111111111111111101111100000)==0b11010101000010000111101001000000) { + names="dc\0"; + d=((ic32>>10)&0x1); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_dc1; args[1]=disasm_arg_Xt; + } else + if((ic32&0b11111111111111111111111111100000)==0b11010101000010110111010000100000) { + names="dc\0"; + t=((ic32>>0)&0x1f); + args[0]=disasm_arg_ZVA; args[1]=disasm_arg_Xt; + } else + if((ic32&0b11111111111111111111101011100000)==0b11010101000010110111101000100000) { + names="dc\0"; + d=((ic32>>9)&0x2)|((ic32>>8)&0x1); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_dc2; args[1]=disasm_arg_Xt; + } else + if((ic32&0b11111111111111001111101111000000)==0b11010101000010000111000100000000) { + names="ic\0"; + c=((ic32>>15)&0x2)|((ic32>>10)&0x1); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_ic; args[1]=disasm_arg_Xt_opt; + } else + if((ic32&0b11111111111111111111101101100000)==0b11010101000011001000000000100000) { + names="tlbi\0"; + n=((ic32>>9)&0x2)|((ic32>>7)&0x1); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_tl1; args[1]=disasm_arg_Xt_opt; + } else + if((ic32&0b11111111111111111111101101000000)==0b11010101000011101000001100000000) { + names="tlbi\0"; + n=((ic32>>8)&0x4)|((ic32>>6)&0x2)|((ic32>>5)&0x1); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_tl2; args[1]=disasm_arg_Xt_opt; + } else + if(((ic32>>8)&0b111111111111110111111111)==0b110101010000110001111000) { + names="at\0"; + a=((ic32>>14)&0x8)|((ic32>>5)&0x7); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_a2; args[1]=disasm_arg_Xt; + } else + if(((ic32>>8)&0b111111111111101111111011)==0b110101010000100010000011) { + names="tlbi\0"; + n=((ic32>>14)&0x10)|((ic32>>7)&0x8)|((ic32>>5)&0x7); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_tl0; args[1]=disasm_arg_Xt_opt; + } else + if(((ic32>>16)&0b1111111111100000)==0b1101010100000000) { + names="msr\0"; + p=((ic32>>19)&0x3); k=((ic32>>16)&0x7); n=((ic32>>12)&0xf); m=((ic32>>8)&0xf); j=((ic32>>5)&0x7); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_sysreg; args[1]=disasm_arg_Xt; + } else + if(((ic32>>16)&0b1111111111111000)==0b1101010100101000) { + names="sysl\0"; + i=((ic32>>18)&1?(-1<<3):0)|((ic32>>16)&0x7); n=((ic32>>12)&0xf); m=((ic32>>8)&0xf); j=((ic32>>5)&0x7); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_i; args[2]=disasm_arg_Cn; args[3]=disasm_arg_Cm; args[4]=disasm_arg_j; + } else + if(((ic32>>16)&0b1111111111100000)==0b1101010100100000) { + names="mrs\0"; + p=((ic32>>19)&0x3); k=((ic32>>16)&0x7); n=((ic32>>12)&0xf); m=((ic32>>8)&0xf); j=((ic32>>5)&0x7); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_sysreg; + } else + if((ic32&0b11111111100111111111110000011111)==0b11010110000111110000000000000000) { + names="br\0blr\0ret\0"; + op=((ic32>>21)&0x3); n=((ic32>>5)&0x1f); + args[0]=disasm_arg_Xn; + } else + if((ic32&0b11111111110111111111111111111111)==0b11010110100111110000001111100000) { + names="eret\0drps\0"; + op=((ic32>>21)&0x1); + } else + if(((ic32>>24)&0b11111111)==0b11011000) { + names="prfm\0"; + i=((ic32>>23)&1?(-1<<19):0)|((ic32>>5)&0x7ffff); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_prf_op; args[1]=disasm_arg_labeli4; + } else + if(((ic32>>8)&0b111111111110000000001100)==0b111110001000000000000000) { + names="prfum\0"; + i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_prf_op; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_i_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b111111111110000000001100)==0b111110001010000000001000) { + names="prfm\0"; + m=((ic32>>16)&0x1f); o=((ic32>>13)&0x7); j=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_prf_op; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_Rom; args[4]=disasm_arg_amountj3; args[5]=disasm_arg_offe; + } else + if(((ic32>>16)&0b1111111111000000)==0b1111100110000000) { + names="prfm\0"; + j=((ic32>>10)&0xfff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_prf_op; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_j_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>16)&0b1011111111100000)==0b1000100000100000) { + names="stxp\0stlxp\0"; + op=((ic32>>15)&0x1); s=((ic32>>30)&0x1); d=((ic32>>16)&0x1f); m=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Wd; args[1]=disasm_arg_Rt; args[2]=disasm_arg_Rm; args[3]=disasm_arg_offs; args[4]=disasm_arg_XnS; args[5]=disasm_arg_offe; + } else + if(((ic32>>16)&0b1011111111111111)==0b1000100001111111) { + names="ldxp\0ldaxp\0"; + op=((ic32>>15)&0x1); s=((ic32>>30)&0x1); m=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rm; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111010000001111100)==0b100010000010000001111100) { + names="cas\0casl\0casa\0casal\0"; + op=((ic32>>21)&0x2)|((ic32>>15)&0x1); s=((ic32>>30)&0x1); d=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rd; args[1]=disasm_arg_Rt; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111110011111101111100)==0b100010000001111101111100) { + names="?\0?\0ldxr\0ldaxr\0stllr\0stlr\0ldlar\0ldar\0"; + op=((ic32>>21)&0x6)|((ic32>>15)&0x1); s=((ic32>>30)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111010000000001100)==0b101110000000000000000100) { + names="str\0ldr\0"; + op=((ic32>>22)&0x1); s=((ic32>>30)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i_opt; + } else + if(((ic32>>8)&0b101111111010000000000100)==0b101110000000000000000000) { + names="stur\0sttr\0ldur\0ldtr\0"; + op=((ic32>>21)&0x2)|((ic32>>11)&0x1); s=((ic32>>30)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_i_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111010000000000100)==0b101110000000000000000100) { + names="str\0ldr\0"; + op=((ic32>>22)&0x1); s=((ic32>>30)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); p=((ic32>>11)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_i_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111111010000000001100)==0b101110000010000000001000) { + names="str\0ldr\0"; + op=((ic32>>22)&0x1); s=((ic32>>30)&0x1); m=((ic32>>16)&0x1f); o=((ic32>>13)&0x7); j=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_Rom; args[4]=disasm_arg_amountjs; args[5]=disasm_arg_offe; + } else + if(((ic32>>8)&0b101111110010000000001100)==0b101110000010000000000000) { + names="ldadd\0ldclr\0ldeor\0ldset\0ldsmax\0ldsmin\0ldumax\0ldumin\0swp\0?\0?\0?\0?\0?\0?\0?\0ldaddl\0ldclrl\0ldeorl\0ldsetl\0ldsmaxl\0ldsminl\0ldumaxl\0lduminl\0swpl\0?\0?\0?\0?\0?\0?\0?\0ldadda\0ldclra\0ldeora\0ldseta\0ldsmaxa\0ldsmina\0ldumaxa\0ldumina\0swpa\0?\0?\0?\0?\0?\0?\0?\0ldaddal\0ldclral\0ldeoral\0ldsetal\0ldsmaxal\0ldsminal\0ldumaxal\0lduminal\0swpal\0"; + op=((ic32>>18)&0x30)|((ic32>>12)&0xf); s=((ic32>>30)&0x1); d=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rd; args[1]=disasm_arg_Rt; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; + } else + if(((ic32>>16)&0b1011111110000000)==0b1011100100000000) { + names="str\0ldr\0"; + op=((ic32>>22)&0x1); s=((ic32>>30)&0x1); j=((ic32>>10)&0xfff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_j_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>16)&0b0111111110100000)==0b0001001110000000) { + names="extr\0"; + s=((ic32>>31)&0x1); m=((ic32>>16)&0x1f); i=((ic32>>15)&1?(-1<<6):0)|((ic32>>10)&0x3f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rn; args[2]=disasm_arg_Rm; args[3]=disasm_arg_i; + } else + if(((ic32>>24)&0b01111100)==0b00010100) { + names="b\0bl\0"; + op=((ic32>>31)&0x1); i=((ic32>>25)&1?(-1<<26):0)|((ic32>>0)&0x3ffffff); + args[0]=disasm_arg_labeli4; + } else + if(((ic32>>8)&0b011111111110000011111100)==0b000110100000000000000000) { + names="adc\0"; + s=((ic32>>31)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rn; args[2]=disasm_arg_Rm; + } else + if(((ic32>>8)&0b011111111110000010000000)==0b000110101100000000000000) { + names="?\0?\0udiv\0sdiv\0?\0?\0?\0?\0lslv\0lsrv\0asrv\0rorv\0?\0?\0?\0?\0crc32b\0crc32h\0crc32w\0crc32x\0crc32cb\0crc32ch\0crc32cw\0crc32cx\0"; + op=((ic32>>10)&0x1f); s=((ic32>>31)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rn; args[2]=disasm_arg_Rm; + } else + if(((ic32>>8)&0b011111111110000001111100)==0b000110110000000001111100) { + names="mul\0mneg\0"; + op=((ic32>>15)&0x1); s=((ic32>>31)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rn; args[2]=disasm_arg_Rm; + } else + if(((ic32>>16)&0b0111111111100000)==0b0001101100000000) { + names="madd\0msub\0"; + op=((ic32>>15)&0x1); s=((ic32>>31)&0x1); m=((ic32>>16)&0x1f); d=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rn; args[2]=disasm_arg_Rm; args[3]=disasm_arg_Rd; + } else + if(((ic32>>8)&0b011111111111111111111100)==0b000111101010111000000000) { + names="fmov\0"; + s=((ic32>>31)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Vn1d; + } else + if(((ic32>>8)&0b011111111111111111111100)==0b000111101010111100000000) { + names="fmov\0"; + s=((ic32>>31)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Vt1d; args[1]=disasm_arg_Rn; + } else + if(((ic32>>16)&0b0111111100111110)==0b0001111000000010) { + names="scvtf\0ucvtf\0"; + op=((ic32>>16)&0x1); s=((ic32>>31)&0x1); z=((ic32>>22)&0x3); j=((ic32>>10)&0x3f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz5t; args[1]=disasm_arg_Rn; args[2]=disasm_arg_fbits; + } else + if(((ic32>>16)&0b0111111100111110)==0b0001111000011000) { + names="fcvtzs\0fcvtzu\0"; + op=((ic32>>16)&0x1); s=((ic32>>31)&0x1); z=((ic32>>22)&0x3); j=((ic32>>10)&0x3f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_FPz5n; args[2]=disasm_arg_fbits; + } else + if(((ic32>>8)&0b011111110011101011111100)==0b000111100010001000000000) { + names="scvtf\0ucvtf\0fmov\0fmov\0"; + op=((ic32>>17)&0x2)|((ic32>>16)&0x1); s=((ic32>>31)&0x1); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPz5t; args[1]=disasm_arg_Rn; + } else + if(((ic32>>8)&0b011111110011000011111100)==0b000111100010000000000000) { + names="fcvtns\0fcvtnu\0scvtf\0ucvtf\0fcvtas\0fcvtau\0fmov\0fmov\0fcvtns\0fcvtnu\0"; + op=((ic32>>16)&0xf); s=((ic32>>31)&0x1); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_FPz5n; + } else + if(((ic32>>8)&0b011111110011111011111100)==0b000111100011000000000000) { + names="fcvtms\0fcvtmu\0"; + op=((ic32>>16)&0x1); s=((ic32>>31)&0x1); z=((ic32>>22)&0x3); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_FPz5n; + } else + if(((ic32>>16)&0b0111111110000000)==0b0010100010000000) { + names="stp\0ldp\0"; + op=((ic32>>22)&0x1); s=((ic32>>31)&0x1); i=((ic32>>21)&1?(-1<<7):0)|((ic32>>15)&0x7f); m=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rm; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; args[5]=disasm_arg_is4_opt; + } else + if(((ic32>>24)&0b01111110)==0b00101000) { + names="stnp\0ldnp\0stp\0ldp\0"; + op=((ic32>>23)&0x2)|((ic32>>22)&0x1); s=((ic32>>31)&0x1); p=((ic32>>23)&0x1); i=((ic32>>21)&1?(-1<<7):0)|((ic32>>15)&0x7f); m=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rm; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_is4_opt; args[5]=disasm_arg_offe; + } else + if(((ic32>>24)&0b01111110)==0b00110100) { + names="cbz\0cbnz\0"; + op=((ic32>>24)&0x1); s=((ic32>>31)&0x1); i=((ic32>>23)&1?(-1<<19):0)|((ic32>>5)&0x7ffff); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_labeli4; + } else + if(((ic32>>24)&0b01111110)==0b00110110) { + names="tbz\0tbnz\0"; + op=((ic32>>24)&0x1); b=((ic32>>26)&0x20)|((ic32>>19)&0x1f); i=((ic32>>18)&1?(-1<<14):0)|((ic32>>5)&0x3fff); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_b; args[2]=disasm_arg_labeli4; + } else + if(((ic32>>8)&0b011111111110000000000100)==0b001110001000000000000000) { + names="?\0ldtrsb\0ldursw\0ldtrsw\0"; + op=((ic32>>30)&0x2)|((ic32>>11)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_i_opt; args[4]=disasm_arg_offe; + } else + if((ic32&0b01111111111000001111111111100000)==0b01011010000000000000001111100000) { + names="ngc\0"; + s=((ic32>>31)&0x1); m=((ic32>>16)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rm; + } else + if(((ic32>>8)&0b011111111111111111111000)==0b010110101100000000001000) { + names="rev\0"; + s=((ic32>>31)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rn; + } else + if(((ic32>>8)&0b011111111111111111101000)==0b010110101100000000000000) { + names="rbit\0rev16\0clz\0cls\0"; + op=((ic32>>11)&0x2)|((ic32>>10)&0x1); s=((ic32>>31)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rn; + } else + if(((ic32>>8)&0b001111111110000000001000)==0b000110101000000000000000) { + names="csel\0csinc\0csinv\0csneg\0"; + op=((ic32>>29)&0x2)|((ic32>>10)&0x1); s=((ic32>>31)&0x1); m=((ic32>>16)&0x1f); c=((ic32>>12)&0xf); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rn; args[2]=disasm_arg_Rm; args[3]=disasm_arg_c; + } else + if(((ic32>>24)&0b00111111)==0b00011100) { + names="ldr\0"; + z=((ic32>>30)&0x3); i=((ic32>>23)&1?(-1<<19):0)|((ic32>>5)&0x7ffff); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_labeli4; + } else + if((ic32&0b00111111111000000000000000011111)==0b00101011001000000000000000011111) { + names="cmn\0cmp\0"; + op=((ic32>>30)&0x1); s=((ic32>>31)&0x1); m=((ic32>>16)&0x1f); o=((ic32>>13)&0x7); j=((ic32>>10)&0x7); n=((ic32>>5)&0x1f); + args[0]=disasm_arg_RnS; args[1]=disasm_arg_Rsom; args[2]=disasm_arg_exts; + } else + if(((ic32>>16)&0b0011111110000000)==0b0010110010000000) { + names="stp\0ldp\0"; + op=((ic32>>22)&0x1); z=((ic32>>30)&0x3); i=((ic32>>21)&1?(-1<<7):0)|((ic32>>15)&0x7f); m=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPm; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_offe; args[5]=disasm_arg_iz4_opt; + } else + if(((ic32>>24)&0b00111110)==0b00101100) { + names="stnp\0ldnp\0stp\0ldp\0"; + op=((ic32>>23)&0x2)|((ic32>>22)&0x1); z=((ic32>>30)&0x3); p=((ic32>>23)&0x1); i=((ic32>>21)&1?(-1<<7):0)|((ic32>>15)&0x7f); m=((ic32>>10)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPt; args[1]=disasm_arg_FPm; args[2]=disasm_arg_offs; args[3]=disasm_arg_XnS; args[4]=disasm_arg_iz4_opt; args[5]=disasm_arg_offe; + } else + if((ic32&0b00111111111000000000110000010000)==0b00111010010000000000000000000000) { + names="ccmn\0ccmp\0"; + op=((ic32>>30)&0x1); s=((ic32>>31)&0x1); m=((ic32>>16)&0x1f); c=((ic32>>12)&0xf); n=((ic32>>5)&0x1f); j=((ic32>>0)&0xf); + args[0]=disasm_arg_Rn; args[1]=disasm_arg_Rm; args[2]=disasm_arg_j; args[3]=disasm_arg_c; + } else + if((ic32&0b00111111111000000000110000010000)==0b00111010010000000000100000000000) { + names="ccmn\0ccmp\0"; + op=((ic32>>30)&0x1); s=((ic32>>31)&0x1); b=((ic32>>16)&0x1f); c=((ic32>>12)&0xf); n=((ic32>>5)&0x1f); j=((ic32>>0)&0xf); + args[0]=disasm_arg_Rn; args[1]=disasm_arg_b; args[2]=disasm_arg_j; args[3]=disasm_arg_c; + } else + if(((ic32>>8)&0b001111110010000000001100)==0b001111000000000000000000) { + names="stur\0ldur\0"; + op=((ic32>>22)&0x1); z=((ic32>>30)&0x3); s=((ic32>>23)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPst; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_i_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b001111110010000000001100)==0b001111000000000000000100) { + names="str\0ldr\0"; + op=((ic32>>22)&0x1); z=((ic32>>30)&0x3); s=((ic32>>23)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPst; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_offe; args[4]=disasm_arg_i_opt; + } else + if(((ic32>>8)&0b001111110010000000000100)==0b001111000000000000000100) { + names="str\0ldr\0"; + op=((ic32>>22)&0x1); z=((ic32>>30)&0x3); s=((ic32>>23)&0x1); i=((ic32>>20)&1?(-1<<9):0)|((ic32>>12)&0x1ff); p=((ic32>>11)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPst; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_i_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>8)&0b001111110010000000001100)==0b001111000010000000001000) { + names="str\0ldr\0"; + op=((ic32>>22)&0x1); z=((ic32>>30)&0x3); s=((ic32>>23)&0x1); m=((ic32>>16)&0x1f); o=((ic32>>13)&0x7); j=((ic32>>12)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPst; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_Rom; args[4]=disasm_arg_amountz; args[5]=disasm_arg_offe; + } else + if(((ic32>>24)&0b00111111)==0b00111101) { + names="str\0ldr\0"; + op=((ic32>>22)&0x1); z=((ic32>>30)&0x3); s=((ic32>>23)&0x1); j=((ic32>>10)&0xfff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_FPst; args[1]=disasm_arg_offs; args[2]=disasm_arg_XnS; args[3]=disasm_arg_j_opt; args[4]=disasm_arg_offe; + } else + if(((ic32>>16)&0b0001111111100000)==0b0000101100100000) { + names="add\0adds\0sub\0subs\0"; + op=((ic32>>29)&0x3); s=((ic32>>31)&0x1); m=((ic32>>16)&0x1f); o=((ic32>>13)&0x7); j=((ic32>>10)&0x7); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_RtS; args[1]=disasm_arg_RnS; args[2]=disasm_arg_Rsom; args[3]=disasm_arg_exts; + } else + if(((ic32>>24)&0b00011110)==0b00001010) { + names="and\0bic\0add\0?\0orr\0orn\0adds\0?\0eor\0eon\0sub\0?\0ands\0bics\0subs\0"; + op=((ic32>>27)&0xc)|((ic32>>23)&0x2)|((ic32>>21)&0x1); s=((ic32>>31)&0x1); z=((ic32>>22)&0x3); m=((ic32>>16)&0x1f); j=((ic32>>10)&0x3f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rn; args[2]=disasm_arg_Rm; args[3]=disasm_arg_shiftj_opt; + } else + if(((ic32>>24)&0b00011111)==0b00010000) { + names="adr\0adrp\0"; + op=((ic32>>31)&0x1); j=((ic32>>29)&0x3); i=((ic32>>23)&1?(-1<<19):0)|((ic32>>5)&0x7ffff); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Xt; args[1]=disasm_arg_labelij1; + } else + if(((ic32>>24)&0b00011111)==0b00010001) { + names="add\0adds\0sub\0subs\0"; + op=((ic32>>29)&0x3); s=((ic32>>31)&0x1); j=((ic32>>22)&0x3); i=((ic32>>21)&1?(-1<<12):0)|((ic32>>10)&0xfff); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_RtS; args[1]=disasm_arg_RnS; args[2]=disasm_arg_i; args[3]=disasm_arg_j12_opt; + } else + if(((ic32>>16)&0b0001111110000000)==0b0001001000000000) { + names="and\0orr\0eor\0ands\0"; + op=((ic32>>29)&0x3); i=((ic32>>22)&1?(-1<<13):0)|((ic32>>10)&0x1000)|((ic32>>4)&0xfc0)|((ic32>>16)&0x3f); s=((ic32>>31)&0x1); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_RtS; args[1]=disasm_arg_Rn; args[2]=disasm_arg_i; + } else + if(((ic32>>16)&0b0001111110000000)==0b0001001010000000) { + names="movn\0?\0movz\0movk\0"; + op=((ic32>>29)&0x3); s=((ic32>>31)&0x1); j=((ic32>>21)&0x3); i=((ic32>>20)&1?(-1<<16):0)|((ic32>>5)&0xffff); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_i; args[2]=disasm_arg_j16_opt; + } else + if(((ic32>>16)&0b0001111110000000)==0b0001001100000000) { + names="sbfm\0bfm\0ubfm\0"; + op=((ic32>>29)&0x3); s=((ic32>>31)&0x1); i=((ic32>>21)&1?(-1<<6):0)|((ic32>>16)&0x3f); j=((ic32>>10)&0x3f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rn; args[2]=disasm_arg_i; args[3]=disasm_arg_j; + } else + if(((ic32>>8)&0b000111111110000011111100)==0b000110100000000000000000) { + names="adc\0adcs\0sbc\0sbcs\0"; + op=((ic32>>29)&0x3); s=((ic32>>31)&0x1); m=((ic32>>16)&0x1f); n=((ic32>>5)&0x1f); t=((ic32>>0)&0x1f); + args[0]=disasm_arg_Rt; args[1]=disasm_arg_Rn; args[2]=disasm_arg_Rm; + } else + names=NULL; + + if(str!=NULL) { + str+=sprintf(str,disasm_str(names,op),disasm_str(conds,c)); + if(str-olds<10)om=10-(str-olds);else om=1;for(op=0;op>3)&3), ((t>>1)&3)+1, disasm_str(prf_pol,t&1)); break; + case disasm_arg_is4_opt: str+=sprintf(str,!i?"":"#0x%x", i<<(2+s)); break; + case disasm_arg_FPm: str+=sprintf(str,"%c%d", z==2?'q':(z==1?'d':'s'), m); break; + case disasm_arg_iz4_opt: str+=sprintf(str,!i?"":"#0x%x", i<<(2+z)); break; + case disasm_arg_im4_opt: str+=sprintf(str,!i?"":"#0x%x", i<<2); break; + case disasm_arg_nRt: str+=sprintf(str,t==31?"%czr":"%c%d", (s?'w':'x'), t); break; + case disasm_arg_FPst: str+=sprintf(str,"%c%d", s==1?'q':(z==3?'d':(z==2?'s':(z==1?'h':'b'))), t); break; + case disasm_arg_j_opt: str+=sprintf(str,!j?"":"#0x%x", j); break; + case disasm_arg_Rom: str+=sprintf(str,m==31?"%czr":"%c%d", (o&1?'x':'w'), m); break; + case disasm_arg_amountj: str+=sprintf(str,"%s", "%s #%d", disasm_str(extend64,o), j); break; + case disasm_arg_amountz: str+=sprintf(str,"%s", "%s #%d", disasm_str(extend64,o), j?(s?4:z):0); break; + case disasm_arg_amountjs: str+=sprintf(str,"%s", "%s #%d", disasm_str(extend64,o), j?(s?3:2):0); break; + case disasm_arg_amountj2: str+=sprintf(str,"%s", "%s #%d", disasm_str(extend64,o), j?2:0); break; + case disasm_arg_amountj3: str+=sprintf(str,"%s", "%s #%d", disasm_str(extend64,o), j?3:0); break; + case disasm_arg_shiftj_opt: str+=sprintf(str,"%s", !j?"":"%s #%d", disasm_str(shift,z), j); break; + case disasm_arg_Rsom: str+=sprintf(str,m==31?"%czr":"%c%d", (s&&(o&3)==3?'x':'w'), m); break; + case disasm_arg_exts: str+=sprintf(str,"%s", "%s #%d", s?disasm_str(extend64,o):disasm_str(extend32,o), j); break; + case disasm_arg_Wn: str+=sprintf(str,n==31?"wzr":"w%d", n); break; + case disasm_arg_Wm: str+=sprintf(str,m==31?"wzr":"w%d", m); break; + case disasm_arg_Xd: str+=sprintf(str,d==31?"xzr":"x%d", d); break; + case disasm_arg_Vt16b: str+=sprintf(str,"V%d.16b", t); break; + case disasm_arg_Vn16b: str+=sprintf(str,"V%d.16b", n); break; + case disasm_arg_Qt: str+=sprintf(str,"q%d", t); break; + case disasm_arg_Sn: str+=sprintf(str,"s%d", n); break; + case disasm_arg_Vm4s: str+=sprintf(str,"V%d.4s", m); break; + case disasm_arg_Vt4s: str+=sprintf(str,"V%d.4s", t); break; + case disasm_arg_Vn4s: str+=sprintf(str,"V%d.4s", n); break; + case disasm_arg_Qn: str+=sprintf(str,"q%d", n); break; + case disasm_arg_St: str+=sprintf(str,"s%d", t); break; + case disasm_arg_FPjt: str+=sprintf(str,"%c%d", j&1?'b':((j&3)==2?'h':((j&7)==4?'s':'d')), t); break; + case disasm_arg_Vnj: str+=sprintf(str,"V%d.%c", n, j&1?'b':((j&3)==2?'h':((j&7)==4?'s':'d'))); break; + case disasm_arg_FPidx: str+=sprintf(str,"%d", j>>(j&1?1:((j&3)==2?2:((j&7)==4?3:4))), t); break; + case disasm_arg_Vtjq: str+=sprintf(str,"%s", "V%d.%s", t, disasm_str(quantum,(j&1?0:((j&3)==2?2:(j&7)==4?4:6))+q)); break; + case disasm_arg_Ht: str+=sprintf(str,"h%d", t); break; + case disasm_arg_Hn: str+=sprintf(str,"h%d", n); break; + case disasm_arg_Hm: str+=sprintf(str,"h%d", m); break; + case disasm_arg_FPn: str+=sprintf(str,"%c%d", z==2?'q':(z==1?'d':'s'), n); break; + case disasm_arg_VtH1: str+=sprintf(str,"V%d.%dh", t, q?8:4); break; + case disasm_arg_VnH1: str+=sprintf(str,"V%d.%dh", n, q?8:4); break; + case disasm_arg_VmH1: str+=sprintf(str,"V%d.%dh", m, q?8:4); break; + case disasm_arg_Vtzq: str+=sprintf(str,"%s", "V%d.%s", t, disasm_str(quantum,4+(z*2)+q)); break; + case disasm_arg_Vnzq: str+=sprintf(str,"%s", "V%d.%s", n, disasm_str(quantum,4+(z*2)+q)); break; + case disasm_arg_Vmzq: str+=sprintf(str,"%s", "V%d.%s", m, disasm_str(quantum,4+(z*2)+q)); break; + case disasm_arg_simd0: str+=sprintf(str,"#0.0"); break; + case disasm_arg_FPz2t: str+=sprintf(str,"%c%d", z==1?'h':'s', t); break; + case disasm_arg_FPz2n: str+=sprintf(str,"%c%d", z==1?'h':'s', n); break; + case disasm_arg_FPz2m: str+=sprintf(str,"%c%d", z==1?'h':'s', m); break; + case disasm_arg_VnT: str+=sprintf(str,"%s", "V%d.%s", n, disasm_str(quantum,(z<<1)|q)); break; + case disasm_arg_VmT: str+=sprintf(str,"%s", "V%d.%s", m, disasm_str(quantum,(z<<1)|q)); break; + case disasm_arg_FPz3t: str+=sprintf(str,"%c%d", z==3?'d':(z==2?'s':(z==1?'h':'b')), t); break; + case disasm_arg_FPz3n: str+=sprintf(str,"%c%d", z==3?'d':(z==2?'s':(z==1?'h':'b')), n); break; + case disasm_arg_FPz4n: str+=sprintf(str,"%c%d", z==2?'d':(z==1?'s':'h'), n); break; + case disasm_arg_VnT3: str+=sprintf(str,"%s", "V%d.%s", n, disasm_str(quantum,(z<<1)+3)); break; + case disasm_arg_Vn2d: str+=sprintf(str,"V%d.2d", n); break; + case disasm_arg_Vn2h: str+=sprintf(str,"V%d.2h", n); break; + case disasm_arg_Vnz: str+=sprintf(str,"V%d.2%c", n, z?'d':'s'); break; + case disasm_arg_FPz4t: str+=sprintf(str,"%c%d", z==2?'d':(z==1?'s':'h'), t); break; + case disasm_arg_Vtz: str+=sprintf(str,"%s", "V%d.%s", t, disasm_str(quantum,4+(z*2))); break; + case disasm_arg_FPz3m: str+=sprintf(str,"%c%d", z==3?'d':(z==2?'s':(z==1?'h':'b')), m); break; + case disasm_arg_Dt: str+=sprintf(str,"d%d", t); break; + case disasm_arg_Dn: str+=sprintf(str,"d%d", n); break; + case disasm_arg_shrshift: str+=sprintf(str,"#%d", ((j>>3)==1?16:((j>>4)==1?32:((j>>5)==1?64:128)))-j); break; + case disasm_arg_Vtj2: str+=sprintf(str,"%s", "V%d.%s", t, disasm_str(quantum,((j>>3)==1?0:((j>>4)==1?2:((j>>5)==1?4:6)))|q)); break; + case disasm_arg_Vnj2: str+=sprintf(str,"%s", "V%d.%s", n, disasm_str(quantum,((j>>3)==1?0:((j>>4)==1?2:((j>>5)==1?4:6)))|q)); break; + case disasm_arg_shlshift: str+=sprintf(str,"#%d", j-((j>>3)==1?8:((j>>4)==1?16:((j>>5)==1?32:64)))); break; + case disasm_arg_FPnj: str+=sprintf(str,"%c%d", (j>>3)==1?'h':((j>>4)==1?'s':'d'), n); break; + case disasm_arg_VnTa: str+=sprintf(str,"%s", "V%d.%s", n, disasm_str(quantum,((j>>3)==1?3:((j>>4)==1?4:7)))); break; + case disasm_arg_FPjt2: str+=sprintf(str,"%c%d", (j>>3)==1?'b':((j>>4)==1?'h':((j>>5)==1?'s':'d')), t); break; + case disasm_arg_FPjn2: str+=sprintf(str,"%c%d", (j>>3)==1?'b':((j>>4)==1?'h':((j>>5)==1?'s':'d')), n); break; + case disasm_arg_Vtz3: str+=sprintf(str,"%s", "V%d.%s", t, disasm_str(quantum,(z<<1)+6)); break; + case disasm_arg_VmTs: str+=sprintf(str,"V%d.%c[%d]", m, z==1?'h':'s', j); break; + case disasm_arg_VmHs: str+=sprintf(str,"V%d.h[%d]", m, j); break; + case disasm_arg_VmTs2: str+=sprintf(str,"V%d.%c[%d]", m, z==1?'d':'s', j); break; + case disasm_arg_Vn116b: str+=sprintf(str,"{ V%d.16b }", n); break; + case disasm_arg_Vn216b: str+=sprintf(str,"{ V%d.16b, V%d.16b }", n, (n+1)&0x1f); break; + case disasm_arg_Vn316b: str+=sprintf(str,"{ V%d.16b, V%d.16b, V%d.16b }", n, (n+1)&0x1f, (n+2)&0x1f); break; + case disasm_arg_Vn416b: str+=sprintf(str,"{ V%d.16b, V%d.16b, V%d.16b, V%d.16b }", n, (n+1)&0x1f, (n+2)&0x1f, (n+3)&0x1f); break; + case disasm_arg_Vtj: str+=sprintf(str,"V%d.%c", t, j&1?'b':((j&3)==2?'h':((j&7)==4?'s':'d'))); break; + case disasm_arg_R2n: str+=sprintf(str,n==31?"%czr":"%c%d", ((j&15)==8?'x':'w'), n); break; + case disasm_arg_FPidxk: str+=sprintf(str,"%d", k>>(k&1?1:((k&3)==2?2:((k&7)==4?3:4))), t); break; + case disasm_arg_Vtzq2: str+=sprintf(str,"%s", "V%d.%s", t, disasm_str(quantum,2+(z*2)+q)); break; + case disasm_arg_VnT2: str+=sprintf(str,"%s", "V%d.%s", n, disasm_str(quantum,z+3)); break; + case disasm_arg_Vnz3: str+=sprintf(str,"%s", "V%d.%s", n, disasm_str(quantum,(z<<1)+6)); break; + case disasm_arg_Vnzq2: str+=sprintf(str,"%s", "V%d.%s", n, disasm_str(quantum,2+(z*2)+q)); break; + case disasm_arg_shift8: str+=sprintf(str,"#%d", 1<<(z+3)); break; + case disasm_arg_VtT3: str+=sprintf(str,"%s", "V%d.%s", t, disasm_str(quantum,(z<<1)+3)); break; + case disasm_arg_VmT3: str+=sprintf(str,"%s", "V%d.%s", m, disasm_str(quantum,(z<<1)+3)); break; + case disasm_arg_VtT4: str+=sprintf(str,"%s", "V%d.%s", t, disasm_str(quantum,z?8:3)); break; + case disasm_arg_imm8: str+=sprintf(str,"#%x", j); break; + case disasm_arg_amountk_opt: str+=sprintf(str,!k?"":"lsl #%d", 1<<(k*3)); break; + case disasm_arg_amountk2_opt: str+=sprintf(str,!k?"":"msl #%d", 1<<(k*3)); break; + case disasm_arg_imm64: str+=sprintf(str,"#0x%02x%02x%02x%02x%02x%02x%02x%02x", j&128?255:0,j&64?255:0,j&32?255:0,j&16?255:0,j&8?255:0,j&4?255:0,j&2?255:0,j&1?255:0); break; + case disasm_arg_Vt2d: str+=sprintf(str,"V%d.2d", t); break; + case disasm_arg_F16: str+=sprintf(str,"#0x02x%02x", (j&128)|(j&64?0:64)|(j&64?32:0)|(j&64?16:0)|((j>>2)&0xF), (j&3)<<6); break; + case disasm_arg_F32: str+=sprintf(str,"#0x02x%02x0000", (j&128)|(j&64?0:64)|(j&64?32:0)|(j&64?16:0)|(j&64?8:0)|(j&64?4:0)|(j&64?2:0)|(j&32?1:0), (j&0x1f)<<3); break; + case disasm_arg_F64: str+=sprintf(str,"#0x02x%02x%06x", (j&128)|(j&64?0:64)|(j&64?32:0)|(j&64?16:0)|(j&64?8:0)|(j&64?4:0)|(j&64?2:0)|(j&64?1:0), (j&64?128:0)|(j&64?64:0)|(j&0x3f), 0); break; + case disasm_arg_VmTs4b: str+=sprintf(str,"V%d.4b[%d]", m, j); break; + case disasm_arg_Vm2d: str+=sprintf(str,"V%d.2d", m); break; + case disasm_arg_Vm16b: str+=sprintf(str,"V%d.16b", m); break; + case disasm_arg_Vd16b: str+=sprintf(str,"V%d.16b", d); break; + case disasm_arg_Vd4s: str+=sprintf(str,"V%d.4s", d); break; + case disasm_arg_FPz5t: str+=sprintf(str,"%c%d", z==1?'d':(z==0?'s':'h'), t); break; + case disasm_arg_fbits: str+=sprintf(str,"#%d", 64-j); break; + case disasm_arg_FPz5n: str+=sprintf(str,"%c%d", z==1?'d':(z==0?'s':'h'), n); break; + case disasm_arg_Vn1d: str+=sprintf(str,"V%d.1d[n]", n); break; + case disasm_arg_Vt1d: str+=sprintf(str,"V%d.1d[1]", t); break; + case disasm_arg_FPk5t: str+=sprintf(str,"%c%d", k==1?'d':(k==0?'s':'h'), t); break; + case disasm_arg_FPz5m: str+=sprintf(str,"%c%d", z==1?'d':(z==0?'s':'h'), m); break; + case disasm_arg_jz: str+=sprintf(str,z==3?"#0x02x%02x":(z==0?"#0x02x%02x0000":"#0x02x%02x%06x"), z==3?(j&128)|(j&64?0:64)|(j&64?32:0)|(j&64?16:0)|((j>>2)&0xF):(j&128)|(j&64?0:64)|(j&64?32:0)|(j&64?16:0)|(j&64?8:0)|(j&64?4:0)|(j&64?2:0)|(j&(z==0?32:64)?1:0),z==3?(j&3)<<6:(z==0?(j&0x1f)<<3:(j&64?128:0)|(j&64?64:0)|(j&0x3f)), 0); break; + case disasm_arg_FPz5d: str+=sprintf(str,"%c%d", z==1?'d':(z==0?'s':'h'), d); break; + default: break; + } + if(*(str-2)==',')str-=2; + } + *str=0; + } + return addr+4; +} + diff --git a/13_debugger/gpio.h b/13_debugger/gpio.h new file mode 100644 index 00000000..52fa671d --- /dev/null +++ b/13_debugger/gpio.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#define MMIO_BASE 0x3F000000 + +#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000)) +#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004)) +#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008)) +#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C)) +#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010)) +#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014)) +#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C)) +#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020)) +#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028)) +#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034)) +#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038)) +#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040)) +#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044)) +#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064)) +#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068)) +#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094)) +#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098)) +#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C)) diff --git a/13_debugger/kernel8.img b/13_debugger/kernel8.img new file mode 100755 index 0000000000000000000000000000000000000000..38a39c9094b03475d544cbf6a6f183644572f402 GIT binary patch literal 79264 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 diff --git a/13_debugger/main.c b/13_debugger/main.c new file mode 100644 index 00000000..e0bf2a30 --- /dev/null +++ b/13_debugger/main.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "uart.h" +#include "dbg.h" + +void main() +{ + // set up serial console + uart_init(); + + // test our debugger + breakpoint; + + // echo everything back + while(1) { + uart_send(uart_getc()); + } +} diff --git a/13_debugger/mbox.c b/13_debugger/mbox.c new file mode 100644 index 00000000..f750c3e4 --- /dev/null +++ b/13_debugger/mbox.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "gpio.h" + +/* mailbox message buffer */ +volatile unsigned int __attribute__((aligned(16))) mbox[36]; + +#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880) +#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0)) +#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10)) +#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14)) +#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18)) +#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C)) +#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20)) +#define MBOX_RESPONSE 0x80000000 +#define MBOX_FULL 0x80000000 +#define MBOX_EMPTY 0x40000000 + +/** + * Make a mailbox call. Returns 0 on failure, non-zero on success + */ +int mbox_call(unsigned char ch) +{ + unsigned int r; + /* wait until we can write to the mailbox */ + do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL); + /* write the address of our message to the mailbox with channel identifier */ + *MBOX_WRITE = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF)); + /* now wait for the response */ + while(1) { + /* is there a response? */ + do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY); + r=*MBOX_READ; + /* is it a response to our message? */ + if((unsigned char)(r&0xF)==ch && (r&~0xF)==(unsigned int)((unsigned long)&mbox)) + /* is it a valid successful response? */ + return mbox[1]==MBOX_RESPONSE; + } + return 0; +} diff --git a/13_debugger/mbox.h b/13_debugger/mbox.h new file mode 100644 index 00000000..09844dea --- /dev/null +++ b/13_debugger/mbox.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/* a properly aligned buffer */ +extern volatile unsigned int mbox[36]; + +#define MBOX_REQUEST 0 + +/* channels */ +#define MBOX_CH_POWER 0 +#define MBOX_CH_FB 1 +#define MBOX_CH_VUART 2 +#define MBOX_CH_VCHIQ 3 +#define MBOX_CH_LEDS 4 +#define MBOX_CH_BTNS 5 +#define MBOX_CH_TOUCH 6 +#define MBOX_CH_COUNT 7 +#define MBOX_CH_PROP 8 + +/* tags */ +#define MBOX_TAG_GETSERIAL 0x10004 +#define MBOX_TAG_SETCLKRATE 0x38002 +#define MBOX_TAG_LAST 0 + +int mbox_call(unsigned char ch); diff --git a/13_debugger/sprintf.c b/13_debugger/sprintf.c new file mode 100644 index 00000000..bc22f3a6 --- /dev/null +++ b/13_debugger/sprintf.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/** + * minimal sprintf implementation + */ +unsigned int vsprintf(char *dst, char* fmt, __builtin_va_list args) +{ + long int arg; + int len, sign, i; + char *p, *orig=dst, tmpstr[19]; + + // failsafes + if(dst==(void*)0 || fmt==(void*)0) { + return 0; + } + + // main loop + arg = 0; + while(*fmt) { + // argument access + if(*fmt=='%') { + fmt++; + // literal % + if(*fmt=='%') { + goto put; + } + len=0; + // size modifier + while(*fmt>='0' && *fmt<='9') { + len *= 10; + len += *fmt-'0'; + fmt++; + } + // skip long modifier + if(*fmt=='l') { + fmt++; + } + // character + if(*fmt=='c') { + arg = __builtin_va_arg(args, int); + *dst++ = (char)arg; + fmt++; + continue; + } else + // decimal number + if(*fmt=='d') { + arg = __builtin_va_arg(args, int); + // check input + sign=0; + if((int)arg<0) { + arg*=-1; + sign++; + } + if(arg>99999999999999999L) { + arg=99999999999999999L; + } + // convert to string + i=18; + tmpstr[i]=0; + do { + tmpstr[--i]='0'+(arg%10); + arg/=10; + } while(arg!=0 && i>0); + if(sign) { + tmpstr[--i]='-'; + } + // padding, only space + if(len>0 && len<18) { + while(i>18-len) { + tmpstr[--i]=' '; + } + } + p=&tmpstr[i]; + goto copystring; + } else + // hex number + if(*fmt=='x') { + arg = __builtin_va_arg(args, long int); + // convert to string + i=16; + tmpstr[i]=0; + do { + char n=arg & 0xf; + // 0-9 => '0'-'9', 10-15 => 'A'-'F' + tmpstr[--i]=n+(n>9?0x37:0x30); + arg>>=4; + } while(arg!=0 && i>0); + // padding, only leading zeros + if(len>0 && len<=16) { + while(i>16-len) { + tmpstr[--i]='0'; + } + } + p=&tmpstr[i]; + goto copystring; + } else + // string + if(*fmt=='s') { + p = __builtin_va_arg(args, char*); +copystring: if(p==(void*)0) { + p="(null)"; + } + while(*p) { + *dst++ = *p++; + } + } + } else { +put: *dst++ = *fmt; + } + fmt++; + } + *dst=0; + // number of bytes written + return dst-orig; +} + +/** + * Variable length arguments + */ +unsigned int sprintf(char *dst, char* fmt, ...) +{ + __builtin_va_list args; + __builtin_va_start(args, fmt); + return vsprintf(dst,fmt,args); +} diff --git a/13_debugger/sprintf.h b/13_debugger/sprintf.h new file mode 100644 index 00000000..2f98dd7c --- /dev/null +++ b/13_debugger/sprintf.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +unsigned int sprintf(char *dst, char* fmt, ...); +unsigned int vsprintf(char *dst,char* fmt, __builtin_va_list args); diff --git a/13_debugger/start.S b/13_debugger/start.S new file mode 100644 index 00000000..d4bb7b19 --- /dev/null +++ b/13_debugger/start.S @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +.section ".text.boot" + +.global _start + +_start: + // read cpu id, stop slave cores + mrs x1, mpidr_el1 + and x1, x1, #3 + cbz x1, 2f + // cpu id > 0, stop +1: wfe + b 1b +2: // cpu id == 0 + + // set stack before our code + ldr x1, =_start + + // set up EL1 + mrs x0, CurrentEL + and x0, x0, #12 // clear reserved bits + + // running at EL3? + cmp x0, #12 + bne 5f + // should never be executed, just for completeness + mov x2, #0x5b1 + msr scr_el3, x2 + mov x2, #0x3c9 + msr spsr_el3, x2 + adr x2, 5f + msr elr_el3, x2 + eret + + // running at EL2? +5: cmp x0, #4 + beq 5f + msr sp_el1, x1 + // enable CNTP for EL1 + mrs x0, cnthctl_el2 + orr x0, x0, #3 + msr cnthctl_el2, x0 + msr cntvoff_el2, xzr + // disable coprocessor traps + mov x0, #0x33FF + msr cptr_el2, x0 + msr hstr_el2, xzr + mov x0, #(3 << 20) + msr cpacr_el1, x0 + // enable AArch64 in EL1 + mov x0, #(1 << 31) // AArch64 + orr x0, x0, #(1 << 1) // SWIO hardwired on Pi3 + msr hcr_el2, x0 + mrs x0, hcr_el2 + // Setup SCTLR access + mov x2, #0x0800 + movk x2, #0x30d0, lsl #16 + msr sctlr_el1, x2 + // set up exception handlers + ldr x2, =_vectors + msr vbar_el1, x2 + // change execution level to EL1 + mov x2, #0x3c4 + msr spsr_el2, x2 + adr x2, 5f + msr elr_el2, x2 + // clear EL1 system registers + msr elr_el1, xzr + msr far_el1, xzr + eret + +5: mov sp, x1 + + // clear bss + ldr x1, =__bss_start + ldr w2, =__bss_size +3: cbz w2, 4f + str xzr, [x1], #8 + sub w2, w2, #1 + cbnz w2, 3b + + // jump to C code, should not return +4: bl main + // for failsafe, halt this core too + b 1b + + // save registers before we call any C code +dbg_saveregs: + str x0, [sp, #-16]! // push x0 + ldr x0, =dbg_regs+8 + str x1, [x0], #8 // dbg_regs[1]=x1 + ldr x1, [sp, #16] // pop x1 + str x1, [x0, #-16]! // dbg_regs[0]=x1 (x0) + add x0, x0, #16 + str x2, [x0], #8 // dbg_regs[2]=x2 + str x3, [x0], #8 // ...etc. + str x4, [x0], #8 + str x5, [x0], #8 + str x6, [x0], #8 + str x7, [x0], #8 + str x8, [x0], #8 + str x9, [x0], #8 + str x10, [x0], #8 + str x11, [x0], #8 + str x12, [x0], #8 + str x13, [x0], #8 + str x14, [x0], #8 + str x15, [x0], #8 + str x16, [x0], #8 + str x17, [x0], #8 + str x18, [x0], #8 + str x19, [x0], #8 + str x20, [x0], #8 + str x21, [x0], #8 + str x22, [x0], #8 + str x23, [x0], #8 + str x24, [x0], #8 + str x25, [x0], #8 + str x26, [x0], #8 + str x27, [x0], #8 + str x28, [x0], #8 + str x29, [x0], #8 + ldr x1, [sp, #16] // pop x30 + str x1, [x0], #8 + // also read and store some system registers + mrs x1, elr_el1 + str x1, [x0], #8 + mrs x1, spsr_el1 + str x1, [x0], #8 + mrs x1, esr_el1 + str x1, [x0], #8 + mrs x1, far_el1 + str x1, [x0], #8 + mrs x1, sctlr_el1 + str x1, [x0], #8 + mrs x1, tcr_el1 + str x1, [x0], #8 + ret + + // important, code has to be properly aligned + .align 11 +_vectors: + // synchronous + .align 7 + str x30, [sp, #-16]! // push x30 + bl dbg_saveregs + mov x0, #0 + bl dbg_decodeexc + bl dbg_main + eret + + // IRQ + .align 7 + str x30, [sp, #-16]! // push x30 + bl dbg_saveregs + mov x0, #1 + bl dbg_decodeexc + bl dbg_main + eret + + // FIQ + .align 7 + str x30, [sp, #-16]! // push x30 + bl dbg_saveregs + mov x0, #2 + bl dbg_decodeexc + bl dbg_main + eret + + // SError + .align 7 + str x30, [sp, #-16]! // push x30 + bl dbg_saveregs + mov x0, #3 + bl dbg_decodeexc + bl dbg_main + eret diff --git a/13_debugger/uart.c b/13_debugger/uart.c new file mode 100644 index 00000000..758259c6 --- /dev/null +++ b/13_debugger/uart.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "gpio.h" +#include "mbox.h" +#include "sprintf.h" + +/* PL011 UART registers */ +#define UART0_DR ((volatile unsigned int*)(MMIO_BASE+0x00201000)) +#define UART0_FR ((volatile unsigned int*)(MMIO_BASE+0x00201018)) +#define UART0_IBRD ((volatile unsigned int*)(MMIO_BASE+0x00201024)) +#define UART0_FBRD ((volatile unsigned int*)(MMIO_BASE+0x00201028)) +#define UART0_LCRH ((volatile unsigned int*)(MMIO_BASE+0x0020102C)) +#define UART0_CR ((volatile unsigned int*)(MMIO_BASE+0x00201030)) +#define UART0_IMSC ((volatile unsigned int*)(MMIO_BASE+0x00201038)) +#define UART0_ICR ((volatile unsigned int*)(MMIO_BASE+0x00201044)) + +// get address from linker +extern volatile unsigned char _end; + +/** + * Set baud rate and characteristics (115200 8N1) and map to GPIO + */ +void uart_init() +{ + register unsigned int r; + + /* initialize UART */ + *UART0_CR = 0; // turn off UART0 + + /* set up clock for consistent divisor values */ + mbox[0] = 8*4; + mbox[1] = MBOX_REQUEST; + mbox[2] = MBOX_TAG_SETCLKRATE; // set clock rate + mbox[3] = 12; + mbox[4] = 8; + mbox[5] = 2; // UART clock + mbox[6] = 4000000; // 4Mhz + mbox[7] = MBOX_TAG_LAST; + mbox_call(MBOX_CH_PROP); + + /* map UART0 to GPIO pins */ + r=*GPFSEL1; + r&=~((7<<12)|(7<<15)); // gpio14, gpio15 + r|=(4<<12)|(4<<15); // alt0 + *GPFSEL1 = r; + *GPPUD = 0; // enable pins 14 and 15 + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = (1<<14)|(1<<15); + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = 0; // flush GPIO setup + + *UART0_ICR = 0x7FF; // clear interrupts + *UART0_IBRD = 2; // 115200 baud + *UART0_FBRD = 0xB; + *UART0_LCRH = 0b11<<5; // 8n1 + *UART0_CR = 0x301; // enable Tx, Rx, FIFO +} + +/** + * Send a character + */ +void uart_send(unsigned int c) { + /* wait until we can send */ + do{asm volatile("nop");}while(*UART0_FR&0x20); + /* write the character to the buffer */ + *UART0_DR=c; +} + +/** + * Receive a character + */ +char uart_getc() { + char r; + /* wait until something is in the buffer */ + do{asm volatile("nop");}while(*UART0_FR&0x10); + /* read it and return */ + r=(char)(*UART0_DR); + /* convert carrige return to newline */ + return r=='\r'?'\n':r; +} + +/** + * Display a string + */ +void printf(char *fmt, ...) { + __builtin_va_list args; + __builtin_va_start(args, fmt); + // we don't have memory allocation yet, so we + // simply place our string after our code + char *s = (char*)&_end; + // use sprintf to format our string + vsprintf(s,fmt,args); + // print out as usual + while(*s) { + /* convert newline to carrige return + newline */ + if(*s=='\n') + uart_send('\r'); + uart_send(*s++); + } +} diff --git a/13_debugger/uart.h b/13_debugger/uart.h new file mode 100644 index 00000000..577a0be8 --- /dev/null +++ b/13_debugger/uart.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +void uart_init(); +void uart_send(unsigned int c); +char uart_getc(); +void printf(char *fmt, ...);