@@ -160,14 +160,15 @@ const Decoder::RingEntry Decoder::Ring64[] = {
160160 {0xfe , 0xda , 2 , &Decoder::opcode_save_fregp_x},
161161 {0xfe , 0xdc , 2 , &Decoder::opcode_save_freg},
162162 {0xff , 0xde , 2 , &Decoder::opcode_save_freg_x},
163+ {0xff , 0xdf , 2 , &Decoder::opcode_alloc_z},
163164 {0xff , 0xe0 , 4 , &Decoder::opcode_alloc_l},
164165 {0xff , 0xe1 , 1 , &Decoder::opcode_setfp},
165166 {0xff , 0xe2 , 2 , &Decoder::opcode_addfp},
166167 {0xff , 0xe3 , 1 , &Decoder::opcode_nop},
167168 {0xff , 0xe4 , 1 , &Decoder::opcode_end},
168169 {0xff , 0xe5 , 1 , &Decoder::opcode_end_c},
169170 {0xff , 0xe6 , 1 , &Decoder::opcode_save_next},
170- {0xff , 0xe7 , 3 , &Decoder::opcode_save_any_reg },
171+ {0xff , 0xe7 , 3 , &Decoder::opcode_e7 },
171172 {0xff , 0xe8 , 1 , &Decoder::opcode_trap_frame},
172173 {0xff , 0xe9 , 1 , &Decoder::opcode_machine_frame},
173174 {0xff , 0xea , 1 , &Decoder::opcode_context},
@@ -805,6 +806,16 @@ bool Decoder::opcode_save_freg_x(const uint8_t *OC, unsigned &Offset,
805806 return false ;
806807}
807808
809+ bool Decoder::opcode_alloc_z (const uint8_t *OC, unsigned &Offset,
810+ unsigned Length, bool Prologue) {
811+ unsigned Off = OC[Offset + 1 ];
812+ SW.startLine () << format (" 0x%02x%02x ; addvl sp, #%d\n " ,
813+ OC[Offset], OC[Offset + 1 ],
814+ Prologue ? -(int )Off : (int )Off);
815+ Offset += 2 ;
816+ return false ;
817+ }
818+
808819bool Decoder::opcode_alloc_l (const uint8_t *OC, unsigned &Offset,
809820 unsigned Length, bool Prologue) {
810821 unsigned Off =
@@ -871,6 +882,24 @@ bool Decoder::opcode_save_next(const uint8_t *OC, unsigned &Offset,
871882 return false ;
872883}
873884
885+ bool Decoder::opcode_e7 (const uint8_t *OC, unsigned &Offset, unsigned Length,
886+ bool Prologue) {
887+ // The e7 opcode has unusual decoding rules; write out the logic.
888+ if ((OC[Offset + 1 ] & 0x80 ) == 0x80 ) {
889+ SW.getOStream () << " reserved encoding\n " ;
890+ Offset += 3 ;
891+ return false ;
892+ }
893+
894+ if ((OC[Offset + 2 ] & 0xC0 ) == 0xC0 ) {
895+ if ((OC[Offset + 1 ] & 0x10 ) == 0 )
896+ return opcode_save_zreg (OC, Offset, Length, Prologue);
897+ return opcode_save_preg (OC, Offset, Length, Prologue);
898+ }
899+
900+ return opcode_save_any_reg (OC, Offset, Length, Prologue);
901+ }
902+
874903bool Decoder::opcode_save_any_reg (const uint8_t *OC, unsigned &Offset,
875904 unsigned Length, bool Prologue) {
876905 // Whether the instruction has writeback
@@ -948,6 +977,30 @@ bool Decoder::opcode_save_any_reg(const uint8_t *OC, unsigned &Offset,
948977 return false ;
949978}
950979
980+ bool Decoder::opcode_save_zreg (const uint8_t *OC, unsigned &Offset,
981+ unsigned Length, bool Prologue) {
982+ uint32_t Reg = (OC[Offset + 1 ] & 0x0F ) + 8 ;
983+ uint32_t Off = ((OC[Offset + 1 ] & 0x60 ) << 1 ) | (OC[Offset + 2 ] & 0x3F );
984+ SW.startLine () << format (
985+ " 0x%02x%02x%02x ; %s z%u, [sp, #%u, mul vl]\n " , OC[Offset],
986+ OC[Offset + 1 ], OC[Offset + 2 ],
987+ static_cast <const char *>(Prologue ? " str" : " ldr" ), Reg, Off);
988+ Offset += 3 ;
989+ return false ;
990+ }
991+
992+ bool Decoder::opcode_save_preg (const uint8_t *OC, unsigned &Offset,
993+ unsigned Length, bool Prologue) {
994+ uint32_t Reg = (OC[Offset + 1 ] & 0x0F );
995+ uint32_t Off = ((OC[Offset + 1 ] & 0x60 ) << 1 ) | (OC[Offset + 2 ] & 0x3F );
996+ SW.startLine () << format (
997+ " 0x%02x%02x%02x ; %s p%u, [sp, #%u, mul vl]\n " , OC[Offset],
998+ OC[Offset + 1 ], OC[Offset + 2 ],
999+ static_cast <const char *>(Prologue ? " str" : " ldr" ), Reg, Off);
1000+ Offset += 3 ;
1001+ return false ;
1002+ }
1003+
9511004bool Decoder::opcode_trap_frame (const uint8_t *OC, unsigned &Offset,
9521005 unsigned Length, bool Prologue) {
9531006 SW.startLine () << format (" 0x%02x ; trap frame\n " , OC[Offset]);
0 commit comments