target/i386/tcg: fix POP to memory in long mode
In long mode, POP to memory will write a full 64-bit value.  However,
the call to gen_writeback() in gen_POP will use MO_32 because the
decoding table is incorrect.
The bug was latent until commit aea49fbb01a ("target/i386: use gen_writeback()
within gen_POP()", 2024-06-08), and then became visible because gen_op_st_v
now receives op->ot instead of the "ot" returned by gen_pop_T0.
Analyzed-by: Clément Chigot <chigot@adacore.com>
Fixes: 5e9e21bcc4d ("target/i386: move 60-BF opcodes to new decoder", 2024-05-07)
Tested-by: Clément Chigot <chigot@adacore.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
			
			
This commit is contained in:
		
							parent
							
								
									340627ec14
								
							
						
					
					
						commit
						3afc6539a8
					
				| @ -1717,7 +1717,7 @@ static const X86OpEntry opcodes_root[256] = { | |||||||
|     [0x8C] = X86_OP_ENTRYwr(MOV, E,v, S,w, op0_Mw), |     [0x8C] = X86_OP_ENTRYwr(MOV, E,v, S,w, op0_Mw), | ||||||
|     [0x8D] = X86_OP_ENTRYwr(LEA, G,v, M,v, nolea), |     [0x8D] = X86_OP_ENTRYwr(LEA, G,v, M,v, nolea), | ||||||
|     [0x8E] = X86_OP_ENTRYwr(MOV, S,w, E,w), |     [0x8E] = X86_OP_ENTRYwr(MOV, S,w, E,w), | ||||||
|     [0x8F] = X86_OP_GROUPw(group1A, E,v), |     [0x8F] = X86_OP_GROUPw(group1A, E,d64), | ||||||
| 
 | 
 | ||||||
|     [0x98] = X86_OP_ENTRY1(CBW,    0,v), /* rAX */ |     [0x98] = X86_OP_ENTRY1(CBW,    0,v), /* rAX */ | ||||||
|     [0x99] = X86_OP_ENTRYwr(CWD,   2,v, 0,v), /* rDX, rAX */ |     [0x99] = X86_OP_ENTRYwr(CWD,   2,v, 0,v), /* rDX, rAX */ | ||||||
|  | |||||||
| @ -2788,6 +2788,7 @@ static void gen_POP(DisasContext *s, X86DecodedInsn *decode) | |||||||
|     X86DecodedOp *op = &decode->op[0]; |     X86DecodedOp *op = &decode->op[0]; | ||||||
|     MemOp ot = gen_pop_T0(s); |     MemOp ot = gen_pop_T0(s); | ||||||
| 
 | 
 | ||||||
|  |     assert(ot >= op->ot); | ||||||
|     if (op->has_ea || op->unit == X86_OP_SEG) { |     if (op->has_ea || op->unit == X86_OP_SEG) { | ||||||
|         /* NOTE: order is important for MMU exceptions */ |         /* NOTE: order is important for MMU exceptions */ | ||||||
|         gen_writeback(s, decode, 0, s->T0); |         gen_writeback(s, decode, 0, s->T0); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Paolo Bonzini
						Paolo Bonzini