summaryrefslogtreecommitdiffstats
path: root/target-i386/translate.c
Commit message (Collapse)AuthorAgeFilesLines
* target-i386: Decode the VEX prefixesRichard Henderson2013-02-181-4/+64
| | | | | | No actual required uses of these encodings yet. Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: Tidy prefix parsingRichard Henderson2013-02-181-82/+52
| | | | | | Avoid duplicating switch statement between 32 and 64-bit modes. Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: Use CC_SRC2 for ADC and SBBRichard Henderson2013-02-181-49/+31
| | | | | | | | Add another slot in ENV and store two of the three inputs. This lets us do less work when carry-out is not needed, and avoids the unpredictable CC_OP after translating these insns. Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: Make helper_cc_compute_{all,c} constRichard Henderson2013-02-181-4/+27
| | | | | | | Pass the data in explicitly, rather than indirectly via env. This avoids all sorts of unnecessary register spillage. Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: optimize flags checking after sub using CC_SRCTRichard Henderson2013-02-181-15/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | After a comparison or subtraction, the original value of the LHS will currently be reconstructed using an addition. However, in most cases it is already available: store it in a temp-local variable and save 1 or 2 TCG ops (2 if the result of the addition needs to be extended). The temp-local can be declared dead as soon as the cc_op changes again, or also before the translation block ends because gen_prepare_cc will always make a copy before returning it. All this magic, plus copy propagation and dead-code elimination, ensures that the temp local will (almost) never be spilled. Example (cmp $0x21,%rax + jbe): Before After ---------------------------------------------------------------------------- movi_i64 tmp1,$0x21 movi_i64 tmp1,$0x21 movi_i64 cc_src,$0x21 movi_i64 cc_src,$0x21 sub_i64 cc_dst,rax,tmp1 sub_i64 cc_dst,rax,tmp1 add_i64 tmp7,cc_dst,cc_src movi_i32 cc_op,$0x11 movi_i32 cc_op,$0x11 brcond_i64 tmp7,cc_src,leu,$0x0 discard loc11 brcond_i64 rax,cc_src,leu,$0x0 Before After ---------------------------------------------------------------------------- mov (%r14),%rbp mov (%r14),%rbp mov %rbp,%rbx mov %rbp,%rbx sub $0x21,%rbx sub $0x21,%rbx lea 0x21(%rbx),%r12 movl $0x11,0xa0(%r14) movl $0x11,0xa0(%r14) movq $0x21,0x90(%r14) movq $0x21,0x90(%r14) mov %rbx,0x98(%r14) mov %rbx,0x98(%r14) cmp $0x21,%r12 | cmp $0x21,%rbp jbe ... jbe ... Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: Update cc_op before TCG branchesRichard Henderson2013-02-181-4/+4
| | | | | | | | | Placing the CC_OP_DYNAMIC at the join is less effective than before the branch, as the branch will have forced global registers to their home locations. This way we have a chance to discard CC_SRC2 before it gets stored. Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: introduce gen_jcc1_noeobRichard Henderson2013-02-181-5/+22
| | | | | | | | | | | | A jump that ends a basic block or otherwise falls back to CC_OP_DYNAMIC will always have to call gen_op_set_cc_op. However, not all jumps end a basic block, so introduce a variant that does not do this. This was partially undone earlier (i386: drop cc_op argument of gen_jcc1), redo it now also to prepare for the introduction of src2. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: use gen_op for cmps/scasRichard Henderson2013-02-181-14/+6
| | | | | | | | Replace low-level ops with a higher-level "cmp %al, (A0)" in the case of scas, and "cmp T0, (A0)" in the case of cmps. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: kill cpu_T3Paolo Bonzini2013-02-181-11/+8
| | | | | | | | | It is almost unused, and it is simpler to pass a TCG value directly to gen_shiftd_rm_T1_T3. This value is then written to t2 without going through a temporary register. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: expand cmov via movcondRichard Henderson2013-02-181-25/+20
| | | | Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: introduce gen_cmovcc1Paolo Bonzini2013-02-181-34/+38
| | | | Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: cleanup temporary macros for CCPreparePaolo Bonzini2013-02-181-47/+39
| | | | | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: inline gen_prepare_cc_slowRichard Henderson2013-02-181-45/+46
| | | | | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: use CCPrepare to generate conditional jumpsPaolo Bonzini2013-02-181-110/+9
| | | | | | | | | This simplifies all the jump generation code. CCPrepare allows the code to create an efficient brcond always, so there is no need to duplicate the setcc and jcc code. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: introduce gen_prepare_ccRichard Henderson2013-02-181-49/+42
| | | | | | | | | | | | | | This makes the i386 front-end able to create CCPrepare structs for all condition, not just those that come from a single flag. In particular, JCC_L and JCC_LE can be optimized because gen_prepare_cc is not forced to return a result in bit 0 (unlike gen_setcc_slow). However, for now the slow jcc operations will still go through CC computation in a single-bit temporary, followed by a brcond if the temporary is nonzero. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: introduce CCPrepareRichard Henderson2013-02-181-54/+93
| | | | | | | | | | | | Introduce a struct that describes how to build a *cond operation that checks for a given x86 condition code. For now, just change gen_compute_eflags_* to return the new struct, generate code for the CCPrepare struct, and go on as before. [rth: Use ctz with the proper width rather than ffs.] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: optimize setcc instructionsPaolo Bonzini2013-02-181-58/+37
| | | | | | | | | Reconstruct the arguments for complex conditions involving CC_OP_SUBx (BE, L, LE). In the others do it via setcond and gen_setcc_slow (which is not that slow in many cases). Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: optimize setleRichard Henderson2013-02-181-9/+6
| | | | | | | And allow gen_setcc_slow to operate on cpu_cc_src. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: optimize setbeRichard Henderson2013-02-181-4/+3
| | | | | | | | | This is looking at EFLAGS, but it can do so more efficiently with setcond. Reviewed-by: Blue Swirl <blauwirbel@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: change gen_setcc_slow_T0 to gen_setcc_slowPaolo Bonzini2013-02-181-19/+20
| | | | | | | | Do not hard code the destination register. Reviewed-by: Blue Swirl <blauwirbel@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: convert gen_compute_eflags_c to TCGRichard Henderson2013-02-181-11/+98
| | | | | | | | | | | | Do the switch at translation time, converting the helper templates to TCG opcodes. In some cases CF can be computed with a single setcond, though others it may require a little more work. In the CC_OP_DYNAMIC case, compute the whole EFLAGS, same as for ZF/SF/PF. Reviewed-by: Blue Swirl <blauwirbel@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: use inverted setcond when computing NS or NZRichard Henderson2013-02-181-18/+31
| | | | | | | | | | | | | Make gen_compute_eflags_z and gen_compute_eflags_s able to compute the inverted condition, and use this in gen_setcc_slow_T0. We cannot do it yet in gen_compute_eflags_c, but prepare the code for it anyway. It is not worthwhile for PF, as usual. shr+and+xor could be replaced by and+setcond. I'm not doing it yet. Reviewed-by: Blue Swirl <blauwirbel@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: do not call helper to compute ZF/SFRichard Henderson2013-02-181-6/+31
| | | | | | | | | | | | ZF, SF and PF can always be computed from CC_DST except in the CC_OP_EFLAGS case (and CC_OP_DYNAMIC, which just resolves to CC_OP_EFLAGS in gen_compute_eflags). Use setcond to compute ZF and SF. We could also use a table lookup to compute PF. Reviewed-by: Blue Swirl <blauwirbel@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: Move CC discards to set_cc_opRichard Henderson2013-02-181-9/+39
| | | | | | | | This gets us universal coverage, rather than scattering discards around at various places. As a bonus, we do not emit redundant discards e.g. between sequential logic insns. Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: no need to flush out cc_op before gen_eobRichard Henderson2013-02-181-3/+1
| | | | | | | | This makes code more similar to the other callers of gen_eob, especially loopz/loopnz/jcxz. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: do not compute eflags multiple times consecutivelyRichard Henderson2013-02-181-36/+36
| | | | | | | | | | | | | After calling gen_compute_eflags, leave the computed value in cc_reg_src and set cc_op to CC_OP_EFLAGS. The next few patches will remove anyway most calls to gen_compute_eflags. As a result of this change it is more natural to remove the register argument from gen_compute_eflags and change all the callers. Reviewed-by: Blue Swirl <blauwirbel@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: add helper functions to get other flagsPaolo Bonzini2013-02-181-12/+36
| | | | | | | | | | Introduce new functions to extract PF, SF, OF, ZF in addition to CF. These provide single entry points for optimizing accesses to a single flag. Reviewed-by: Blue Swirl <blauwirbel@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: Use gen_update_cc_op everywhereRichard Henderson2013-02-181-120/+57
| | | | | | | All of the conditional calls to gen_op_set_cc_op go away, and gen_op_set_cc_op itself gets inlined into its only remaining caller. Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: Don't clobber s->cc_op in gen_update_cc_opRichard Henderson2013-02-181-15/+22
| | | | | | | Use a dirty flag to know whether env->cc_op is up to date, rather than forcing s->cc_op to DYNAMIC and losing info. Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: Introduce set_cc_opRichard Henderson2013-02-181-65/+69
| | | | | | | This will provide a good hook into which we can consolidate all of the cc variable discards. Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: Name the cc_op enumerationRichard Henderson2013-02-181-1/+1
| | | | Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: factor gen_op_set_cc_op/tcg_gen_discard_tl around computing flagsPaolo Bonzini2013-02-181-66/+37
| | | | | | | | | | | | | Before computing flags we need to store the cc_op to memory. Move this to gen_compute_eflags_c and gen_compute_eflags rather than doing it all over the place. Alo, after computing the flags in cpu_cc_src we are in EFLAGS mode. Set s->cc_op and discard cpu_cc_dst in gen_compute_eflags, rather than doing it all over the place. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: use gen_jcc1 to compile loopzPaolo Bonzini2013-02-181-7/+1
| | | | | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: clean up sahfPaolo Bonzini2013-02-181-1/+3
| | | | | | | Discard CC_DST and set s->cc_op immediately after computing EFLAGS. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: compute eflags outside rcl/rcr helperPaolo Bonzini2013-02-181-16/+4
| | | | | | | | | | | | | | Always compute EFLAGS first since it is needed whenever the shift is non-zero, i.e. most of the time. This makes it possible to remove some writes of CC_OP_EFLAGS to cpu_cc_op and more importantly removes cases where s->cc_op becomes CC_OP_DYNAMIC. Also, we can remove cc_tmp and just modify cc_src from within the helper. Finally, always follow gen_compute_eflags(cpu_cc_src) by setting s->cc_op and discarding cpu_cc_dst. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: move eflags computation closer to gen_op_set_cc_opPaolo Bonzini2013-02-181-11/+8
| | | | | | | | | | | | | | | | | | | This ensures the invariant that cpu_cc_op matches s->cc_op when calling the helpers. The next patches need this because gen_compute_eflags and gen_compute_eflags_c will take care of setting cpu_cc_op. Always compute EFLAGS first since it is needed whenever the shift is non-zero, i.e. most of the time. This makes it possible to remove some writes of CC_OP_EFLAGS to cpu_cc_op and more importantly removes cases where s->cc_op becomes CC_OP_DYNAMIC. These are slow and we want to avoid them: CC_OP_EFLAGS is quite efficient once we paid the initial cost of computing the flags. Finally, always follow gen_compute_eflags(cpu_cc_src) by setting s->cc_op and discarding cpu_cc_dst. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: move carry computation for inc/dec closer to gen_op_set_cc_opPaolo Bonzini2013-02-181-1/+1
| | | | | | | | | This ensures the invariant that cpu_cc_op matches s->cc_op when calling the helpers. The next patches need this because gen_compute_eflags and gen_compute_eflags_c will take care of setting cpu_cc_op. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: drop cc_op argument of gen_jcc1Paolo Bonzini2013-02-181-15/+18
| | | | | | | | | | As in the gen_repz_scas/gen_repz_cmps case, delay setting CC_OP_DYNAMIC in gen_jcc until after code generation. All of gen_jcc1/is_fast_jcc/gen_setcc_slow_T0 now work on s->cc_op, which makes things a bit easier to follow and to patch. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: factor setting of s->cc_op handling for string functionsPaolo Bonzini2013-02-181-4/+5
| | | | | | | | | Set it to the appropriate CC_OP_SUBx constant in gen_scas/gen_cmps. In the repz case it can be overridden to CC_OP_DYNAMIC after generating the code. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: introduce gen_ext_tlPaolo Bonzini2013-02-181-109/+37
| | | | | | | | | Introduce a function that abstracts extracting an 8, 16, 32 or 64-bit value with or without sign, generalizing gen_extu and gen_exts. Reviewed-by: Blue Swirl <blauwirbel@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* target-i386: use OT_* consistentlyPaolo Bonzini2013-02-181-39/+49
| | | | | | Reviewed-by: Blue Swirl <blauwirbel@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
* qemu-log: Rename the public-facing cpu_set_log function to qemu_set_logPeter Maydell2013-02-161-1/+1
| | | | | | | | | | Rename the public-facing function cpu_set_log to qemu_set_log. This requires us to rename the internal-only qemu_set_log() to do_qemu_set_log(). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Andreas Färber <afaerber@suse.de> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
* exec: move include files to include/exec/Paolo Bonzini2012-12-191-1/+1
| | | | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* build: kill libdis, move disassemblers to disas/Paolo Bonzini2012-12-191-1/+1
| | | | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
* TCG: Use gen_opc_instr_start from context instead of global variable.Evgeny Voevodin2012-12-081-4/+4
| | | | | Signed-off-by: Evgeny Voevodin <e.voevodin@samsung.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
* TCG: Use gen_opc_icount from context instead of global variable.Evgeny Voevodin2012-12-081-1/+1
| | | | | Signed-off-by: Evgeny Voevodin <e.voevodin@samsung.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
* TCG: Use gen_opc_pc from context instead of global variable.Evgeny Voevodin2012-12-081-4/+5
| | | | | Signed-off-by: Evgeny Voevodin <e.voevodin@samsung.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
* TCG: Use gen_opc_buf from context instead of global variable.Evgeny Voevodin2012-11-171-3/+3
| | | | | | Signed-off-by: Evgeny Voevodin <e.voevodin@samsung.com> Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
* TCG: Use gen_opc_ptr from context instead of global variable.Evgeny Voevodin2012-11-171-4/+4
| | | | | | Signed-off-by: Evgeny Voevodin <e.voevodin@samsung.com> Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
* target-i386: avoid using cpu_single_envBlue Swirl2012-11-101-218/+222
| | | | | | | Pass around CPUArchState instead of using global cpu_single_env. Signed-off-by: Blue Swirl <blauwirbel@gmail.com> Reviewed-by: Andreas Färber <afaerber@suse.de>
OpenPOWER on IntegriCloud