mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	armemu: Join SMUAD, SMUSD, and SMLAD
This commit is contained in:
		
							parent
							
								
									0fd731ee63
								
							
						
					
					
						commit
						0f9e3baf39
					
				
					 1 changed files with 32 additions and 35 deletions
				
			
		|  | @ -6222,45 +6222,42 @@ L_stm_s_takeabort: | ||||||
| 			return 1; | 			return 1; | ||||||
| 		} | 		} | ||||||
|         case 0x70: |         case 0x70: | ||||||
|             if ((instr & 0xf0d0) == 0xf010) { //smuad //ichfly
 |             // ichfly
 | ||||||
|                 u8 tar = BITS(16, 19); |             // SMUAD, SMUSD, SMLAD
 | ||||||
|                 u8 src1 = BITS(0, 3); |             if ((instr & 0xf0d0) == 0xf010 || (instr & 0xf0d0) == 0xf050 || (instr & 0xd0) == 0x10) { | ||||||
|                 u8 src2 = BITS(8, 11); |                 const u8 rd_idx = BITS(16, 19); | ||||||
|                 u8 swap = BIT(5); |                 const u8 rn_idx = BITS(0, 3); | ||||||
|                 s16 a1 = (state->Reg[src1] & 0xFFFF); |                 const u8 rm_idx = BITS(8, 11); | ||||||
|                 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); |                 const bool do_swap = (BIT(5) == 1); | ||||||
|                 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF); |  | ||||||
|                 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); |  | ||||||
|                 state->Reg[tar] = a1*a2 + b1*b2; |  | ||||||
|                 return 1; |  | ||||||
| 
 | 
 | ||||||
|             } else if ((instr & 0xf0d0) == 0xf050) { //smusd
 |                 u32 rm_val = state->Reg[rm_idx]; | ||||||
|                 u8 tar = BITS(16, 19); |                 const u32 rn_val = state->Reg[rn_idx]; | ||||||
|                 u8 src1 = BITS(0, 3); |  | ||||||
|                 u8 src2 = BITS(8, 11); |  | ||||||
|                 u8 swap = BIT(5); |  | ||||||
|                 s16 a1 = (state->Reg[src1] & 0xFFFF); |  | ||||||
|                 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); |  | ||||||
|                 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF); |  | ||||||
|                 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); |  | ||||||
|                 state->Reg[tar] = a1*a2 - b1*b2; |  | ||||||
|                 return 1; |  | ||||||
|             } else if ((instr & 0xd0) == 0x10) { //smlad
 |  | ||||||
|                 u8 tar = BITS(16, 19); |  | ||||||
|                 u8 src1 = BITS(0, 3); |  | ||||||
|                 u8 src2 = BITS(8, 11); |  | ||||||
|                 u8 src3 = BITS(12, 15); |  | ||||||
|                 u8 swap = BIT(5); |  | ||||||
| 
 | 
 | ||||||
|                 u32 a3 = state->Reg[src3]; |                 if (do_swap) | ||||||
|  |                     rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); | ||||||
| 
 | 
 | ||||||
|                 s16 a1 = (state->Reg[src1] & 0xFFFF); |                 const s16 rm_lo = (rm_val & 0xFFFF); | ||||||
|                 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); |                 const s16 rm_hi = ((rm_val >> 16) & 0xFFFF); | ||||||
|                 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF); |                 const s16 rn_lo = (rn_val & 0xFFFF); | ||||||
|                 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); |                 const s16 rn_hi = ((rn_val >> 16) & 0xFFFF); | ||||||
|                 state->Reg[tar] = a1*a2 + b1*b2 + a3; | 
 | ||||||
|  |                 // SMUAD
 | ||||||
|  |                 if ((instr & 0xf0d0) == 0xf010) { | ||||||
|  |                     state->Reg[rd_idx] = (rn_lo * rn_hi) + (rm_lo * rm_hi); | ||||||
|  |                 } | ||||||
|  |                 // SMUSD
 | ||||||
|  |                 else if ((instr & 0xf0d0) == 0xf050) { | ||||||
|  |                     state->Reg[rd_idx] = (rn_lo * rn_hi) - (rm_lo * rm_hi); | ||||||
|  |                 } | ||||||
|  |                 // SMLAD
 | ||||||
|  |                 else { | ||||||
|  |                     const u8 ra_idx = BITS(12, 15); | ||||||
|  |                     state->Reg[rd_idx] = (rn_lo * rn_hi) + (rm_lo * rm_hi) + (s32)state->Reg[ra_idx]; | ||||||
|  |                 } | ||||||
|                 return 1; |                 return 1; | ||||||
|             } else printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); |             } else { | ||||||
|  |                 printf ("Unhandled v6 insn: smlsd\n"); | ||||||
|  |             } | ||||||
|             break; |             break; | ||||||
|         case 0x74: |         case 0x74: | ||||||
|             printf ("Unhandled v6 insn: smlald/smlsld\n"); |             printf ("Unhandled v6 insn: smlald/smlsld\n"); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue