From mboxrd@z Thu Jan 1 00:00:00 1970 From: Guillaume Thouvenin Subject: Re: [Patch 4/5] x86_emulator: add the assembler code for three operands Date: Tue, 25 Nov 2008 08:59:18 +0100 Message-ID: <20081125085918.45bb29d2@frecb000711> References: <20081103160036.499cb482@frecb000711> <20081103160504.3fa8c378@frecb000711> <4910222A.20201@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Cc: kvm To: Avi Kivity Return-path: Received: from ecfrec.frec.bull.fr ([129.183.4.8]:35527 "EHLO ecfrec.frec.bull.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751562AbYKYH7h (ORCPT ); Tue, 25 Nov 2008 02:59:37 -0500 In-Reply-To: <4910222A.20201@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: On Tue, 04 Nov 2008 12:21:30 +0200 Avi Kivity wrote: > Guillaume Thouvenin wrote: > > Add the assembler code for three operands > > > > > > +/* Instruction has three operands */ > > +/* In the switch we only implement case 4 because we know that for shld instruction > > + * bytes are equal to 4. When eveything will be fine, we will add others cases. > > > > No, shld is defined for 16, 32, and 64 bit operands. Need to implement > those too. I tried something like: +/* Instruction has three operands */ +/* In the switch we only implement case 4 because we know that for shld instruction + * bytes are equal to 4. When eveything will be fine, we will add others cases. + */ +#define __emulate_2op_cl(_op,_src,_src2,_dst,_eflags,_by,_bx,_wx,_wy,_lx,_ly,_qx,_qy) \ + do { \ + unsigned long _tmp; \ + \ + switch((_dst).bytes) { \ + case 2: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "5", "2") \ + "mov %4, %%rcx \n\t" \ + _op"w %%cl,%3,%1; \n\t" \ + _POST_EFLAGS("0", "5", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _wy ((_src).val) , _wy ((_src2).val), "i" (EFLAGS_MASK) \ + : "%rcx" ); \ + break; \ + case 4: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "5", "2") \ + "mov %4, %%rcx \n\t" \ + _op"l %%cl,%3,%1; \n\t" \ + _POST_EFLAGS("0", "5", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _ly ((_src).val) , _ly ((_src2).val), "i" (EFLAGS_MASK) \ + : "%rcx" ); \ + break; \ + case 8: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "5", "2") \ + "mov %4, %%rcx \n\t" \ + _op"q %%cl,%3,%1; \n\t" \ + _POST_EFLAGS("0", "5", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _ly ((_src).val) , _ly ((_src2).val), "i" (EFLAGS_MASK) \ + : "%rcx" ); \ + break; \ + } \ + } while (0) + +#define emulate_2op_cl(_op, _src, _src2, _dst, _eflags) \ + __emulate_2op_cl(_op, _src, _src2, _dst, _eflags, \ + "b", "r", "b", "r", "b", "r", "b", "r") + but it doesn't work because shld can not be used with suffix 'l' or 'w' etc... Is the solution is to have a single case for all operand size like: +#define __emulate_2op_cl(_op,_src,_src2,_dst,_eflags,_wx,_wy) \ + do { \ + unsigned long _tmp; \ + \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "5", "2") \ + "mov %4, %%rcx \n\t" \ + _op" %%cl,%3,%1; \n\t" \ + _POST_EFLAGS("0", "5", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _wy ((_src).val) , _wy ((_src2).val), "i" (EFLAGS_MASK) \ + : "%rcx" ); \ + } while (0) I tested the code and it seems to work. Excuse me for the delay of this answer, Regards, Guillaume