Commit 4fa551d76893dfdd976d2745a42c17ca1cedaa55

Authored by ths
1 parent 5478670f

CRIS micro-ops, by Edgar E. Iglesias.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3360 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 1289 additions and 0 deletions
target-cris/op.c 0 → 100644
  1 +/*
  2 + * CRIS emulation micro-operations for qemu.
  3 + *
  4 + * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +#include "exec.h"
  21 +
  22 +#define REGNAME r0
  23 +#define REG (env->regs[0])
  24 +#include "op_template.h"
  25 +
  26 +#define REGNAME r1
  27 +#define REG (env->regs[1])
  28 +#include "op_template.h"
  29 +
  30 +#define REGNAME r2
  31 +#define REG (env->regs[2])
  32 +#include "op_template.h"
  33 +
  34 +#define REGNAME r3
  35 +#define REG (env->regs[3])
  36 +#include "op_template.h"
  37 +
  38 +#define REGNAME r4
  39 +#define REG (env->regs[4])
  40 +#include "op_template.h"
  41 +
  42 +#define REGNAME r5
  43 +#define REG (env->regs[5])
  44 +#include "op_template.h"
  45 +
  46 +#define REGNAME r6
  47 +#define REG (env->regs[6])
  48 +#include "op_template.h"
  49 +
  50 +#define REGNAME r7
  51 +#define REG (env->regs[7])
  52 +#include "op_template.h"
  53 +
  54 +#define REGNAME r8
  55 +#define REG (env->regs[8])
  56 +#include "op_template.h"
  57 +
  58 +#define REGNAME r9
  59 +#define REG (env->regs[9])
  60 +#include "op_template.h"
  61 +
  62 +#define REGNAME r10
  63 +#define REG (env->regs[10])
  64 +#include "op_template.h"
  65 +
  66 +#define REGNAME r11
  67 +#define REG (env->regs[11])
  68 +#include "op_template.h"
  69 +
  70 +#define REGNAME r12
  71 +#define REG (env->regs[12])
  72 +#include "op_template.h"
  73 +
  74 +#define REGNAME r13
  75 +#define REG (env->regs[13])
  76 +#include "op_template.h"
  77 +
  78 +#define REGNAME r14
  79 +#define REG (env->regs[14])
  80 +#include "op_template.h"
  81 +
  82 +#define REGNAME r15
  83 +#define REG (env->regs[15])
  84 +#include "op_template.h"
  85 +
  86 +
  87 +#define REGNAME p0
  88 +#define REG (env->pregs[0])
  89 +#include "op_template.h"
  90 +
  91 +#define REGNAME p1
  92 +#define REG (env->pregs[1])
  93 +#include "op_template.h"
  94 +
  95 +#define REGNAME p2
  96 +#define REG (env->pregs[2])
  97 +#include "op_template.h"
  98 +
  99 +#define REGNAME p3
  100 +#define REG (env->pregs[3])
  101 +#include "op_template.h"
  102 +
  103 +#define REGNAME p4
  104 +#define REG (env->pregs[4])
  105 +#include "op_template.h"
  106 +
  107 +#define REGNAME p5
  108 +#define REG (env->pregs[5])
  109 +#include "op_template.h"
  110 +
  111 +#define REGNAME p6
  112 +#define REG (env->pregs[6])
  113 +#include "op_template.h"
  114 +
  115 +#define REGNAME p7
  116 +#define REG (env->pregs[7])
  117 +#include "op_template.h"
  118 +
  119 +#define REGNAME p8
  120 +#define REG (env->pregs[8])
  121 +#include "op_template.h"
  122 +
  123 +#define REGNAME p9
  124 +#define REG (env->pregs[9])
  125 +#include "op_template.h"
  126 +
  127 +#define REGNAME p10
  128 +#define REG (env->pregs[10])
  129 +#include "op_template.h"
  130 +
  131 +#define REGNAME p11
  132 +#define REG (env->pregs[11])
  133 +#include "op_template.h"
  134 +
  135 +#define REGNAME p12
  136 +#define REG (env->pregs[12])
  137 +#include "op_template.h"
  138 +
  139 +#define REGNAME p13
  140 +#define REG (env->pregs[13])
  141 +#include "op_template.h"
  142 +
  143 +#define REGNAME p14
  144 +#define REG (env->pregs[14])
  145 +#include "op_template.h"
  146 +
  147 +#define REGNAME p15
  148 +#define REG (env->pregs[15])
  149 +#include "op_template.h"
  150 +
  151 +/* Microcode. */
  152 +
  153 +void OPPROTO op_exit_tb (void)
  154 +{
  155 + EXIT_TB();
  156 +}
  157 +
  158 +void OPPROTO op_goto_tb0 (void)
  159 +{
  160 + GOTO_TB(op_goto_tb0, PARAM1, 0);
  161 + RETURN();
  162 +}
  163 +
  164 +void OPPROTO op_goto_tb1 (void)
  165 +{
  166 + GOTO_TB(op_goto_tb1, PARAM1, 1);
  167 + RETURN();
  168 +}
  169 +
  170 +void OPPROTO op_break_im(void)
  171 +{
  172 + env->trapnr = PARAM1;
  173 + env->exception_index = EXCP_BREAK;
  174 + cpu_loop_exit();
  175 +}
  176 +
  177 +void OPPROTO op_debug(void)
  178 +{
  179 + env->exception_index = EXCP_DEBUG;
  180 + cpu_loop_exit();
  181 +}
  182 +
  183 +void OPPROTO op_exec_insn(void)
  184 +{
  185 + env->stats.exec_insns++;
  186 + RETURN();
  187 +}
  188 +void OPPROTO op_exec_load(void)
  189 +{
  190 + env->stats.exec_loads++;
  191 + RETURN();
  192 +}
  193 +void OPPROTO op_exec_store(void)
  194 +{
  195 + env->stats.exec_stores++;
  196 + RETURN();
  197 +}
  198 +
  199 +void OPPROTO op_ccs_lshift (void)
  200 +{
  201 + uint32_t ccs;
  202 +
  203 + /* Apply the ccs shift. */
  204 + ccs = env->pregs[SR_CCS];
  205 + ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);
  206 + env->pregs[SR_CCS] = ccs;
  207 +}
  208 +void OPPROTO op_ccs_rshift (void)
  209 +{
  210 + uint32_t ccs;
  211 +
  212 + /* Apply the ccs shift. */
  213 + ccs = env->pregs[SR_CCS];
  214 + ccs = (ccs & 0xc0000000) | (ccs >> 10);
  215 + env->pregs[SR_CCS] = ccs;
  216 +}
  217 +
  218 +void OPPROTO op_setf (void)
  219 +{
  220 + env->pregs[SR_CCS] |= PARAM1;
  221 + RETURN();
  222 +}
  223 +
  224 +void OPPROTO op_clrf (void)
  225 +{
  226 + env->pregs[SR_CCS] &= ~PARAM1;
  227 + RETURN();
  228 +}
  229 +
  230 +void OPPROTO op_movl_debug1_T0 (void)
  231 +{
  232 + env->debug1 = T0;
  233 + RETURN();
  234 +}
  235 +
  236 +void OPPROTO op_movl_debug2_T0 (void)
  237 +{
  238 + env->debug2 = T0;
  239 + RETURN();
  240 +}
  241 +
  242 +void OPPROTO op_movl_debug3_T0 (void)
  243 +{
  244 + env->debug3 = T0;
  245 + RETURN();
  246 +}
  247 +void OPPROTO op_movl_debug1_T1 (void)
  248 +{
  249 + env->debug1 = T1;
  250 + RETURN();
  251 +}
  252 +
  253 +void OPPROTO op_movl_debug2_T1 (void)
  254 +{
  255 + env->debug2 = T1;
  256 + RETURN();
  257 +}
  258 +
  259 +void OPPROTO op_movl_debug3_T1 (void)
  260 +{
  261 + env->debug3 = T1;
  262 + RETURN();
  263 +}
  264 +void OPPROTO op_movl_debug3_im (void)
  265 +{
  266 + env->debug3 = PARAM1;
  267 + RETURN();
  268 +}
  269 +void OPPROTO op_movl_T0_flags (void)
  270 +{
  271 + T0 = env->pregs[SR_CCS];
  272 + RETURN();
  273 +}
  274 +void OPPROTO op_movl_flags_T0 (void)
  275 +{
  276 + env->pregs[SR_CCS] = T0;
  277 + RETURN();
  278 +}
  279 +
  280 +void OPPROTO op_movl_sreg_T0 (void)
  281 +{
  282 + env->sregs[env->pregs[SR_SRS]][PARAM1] = T0;
  283 + RETURN();
  284 +}
  285 +
  286 +void OPPROTO op_movl_tlb_lo_T0 (void)
  287 +{
  288 + int srs;
  289 + srs = env->pregs[SR_SRS];
  290 + if (srs == 1 || srs == 2)
  291 + {
  292 + int set;
  293 + int idx;
  294 + uint32_t lo, hi;
  295 +
  296 + idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
  297 + set >>= 4;
  298 + set &= 3;
  299 +
  300 + idx &= 31;
  301 + /* We've just made a write to tlb_lo. */
  302 + lo = env->sregs[SFR_RW_MM_TLB_LO];
  303 + hi = env->sregs[SFR_RW_MM_TLB_HI];
  304 + env->tlbsets[srs - 1][set][idx].lo = lo;
  305 + env->tlbsets[srs - 1][set][idx].hi = hi;
  306 + }
  307 +
  308 + RETURN();
  309 +}
  310 +
  311 +void OPPROTO op_movl_T0_sreg (void)
  312 +{
  313 + T0 = env->sregs[env->pregs[SR_SRS]][PARAM1];
  314 + RETURN();
  315 +}
  316 +
  317 +void OPPROTO op_update_cc (void)
  318 +{
  319 + env->cc_op = PARAM1;
  320 + env->cc_dest = PARAM2;
  321 + env->cc_src = PARAM3;
  322 + RETURN();
  323 +}
  324 +
  325 +void OPPROTO op_update_cc_op (void)
  326 +{
  327 + env->cc_op = PARAM1;
  328 + RETURN();
  329 +}
  330 +
  331 +void OPPROTO op_update_cc_mask (void)
  332 +{
  333 + env->cc_mask = PARAM1;
  334 + RETURN();
  335 +}
  336 +
  337 +void OPPROTO op_update_cc_dest_T0 (void)
  338 +{
  339 + env->cc_dest = T0;
  340 + RETURN();
  341 +}
  342 +
  343 +void OPPROTO op_update_cc_result_T0 (void)
  344 +{
  345 + env->cc_result = T0;
  346 + RETURN();
  347 +}
  348 +
  349 +void OPPROTO op_update_cc_size_im (void)
  350 +{
  351 + env->cc_size = PARAM1;
  352 + RETURN();
  353 +}
  354 +
  355 +void OPPROTO op_update_cc_src_T1 (void)
  356 +{
  357 + env->cc_src = T1;
  358 + RETURN();
  359 +}
  360 +void OPPROTO op_update_cc_x (void)
  361 +{
  362 + env->cc_x_live = PARAM1;
  363 + env->cc_x = PARAM2;
  364 + RETURN();
  365 +}
  366 +
  367 +/* FIXME: is this allowed? */
  368 +extern inline void evaluate_flags_writeback(uint32_t flags)
  369 +{
  370 + int x;
  371 +
  372 + /* Extended arithmetics, leave the z flag alone. */
  373 + env->debug3 = env->pregs[SR_CCS];
  374 +
  375 + if (env->cc_x_live)
  376 + x = env->cc_x;
  377 + else
  378 + x = env->pregs[SR_CCS] & X_FLAG;
  379 +
  380 + if ((x || env->cc_op == CC_OP_ADDC)
  381 + && flags & Z_FLAG)
  382 + env->cc_mask &= ~Z_FLAG;
  383 +
  384 + /* all insn clear the x-flag except setf or clrf. */
  385 + env->pregs[SR_CCS] &= ~(env->cc_mask | X_FLAG);
  386 + flags &= env->cc_mask;
  387 + env->pregs[SR_CCS] |= flags;
  388 + RETURN();
  389 +}
  390 +
  391 +void OPPROTO op_evaluate_flags_muls(void)
  392 +{
  393 + uint32_t src;
  394 + uint32_t dst;
  395 + uint32_t res;
  396 + uint32_t flags = 0;
  397 + /* were gonna have to redo the muls. */
  398 + int64_t tmp, t0 ,t1;
  399 + int32_t mof;
  400 + int dneg;
  401 +
  402 + src = env->cc_src;
  403 + dst = env->cc_dest;
  404 + res = env->cc_result;
  405 +
  406 +
  407 + /* cast into signed values to make GCC sign extend. */
  408 + t0 = (int32_t)src;
  409 + t1 = (int32_t)dst;
  410 + dneg = ((int32_t)res) < 0;
  411 +
  412 + tmp = t0 * t1;
  413 + mof = tmp >> 32;
  414 + if (tmp == 0)
  415 + flags |= Z_FLAG;
  416 + else if (tmp < 0)
  417 + flags |= N_FLAG;
  418 + if ((dneg && mof != -1)
  419 + || (!dneg && mof != 0))
  420 + flags |= V_FLAG;
  421 + evaluate_flags_writeback(flags);
  422 + RETURN();
  423 +}
  424 +
  425 +void OPPROTO op_evaluate_flags_mulu(void)
  426 +{
  427 + uint32_t src;
  428 + uint32_t dst;
  429 + uint32_t res;
  430 + uint32_t flags = 0;
  431 + /* were gonna have to redo the muls. */
  432 + uint64_t tmp, t0 ,t1;
  433 + uint32_t mof;
  434 +
  435 + src = env->cc_src;
  436 + dst = env->cc_dest;
  437 + res = env->cc_result;
  438 +
  439 +
  440 + /* cast into signed values to make GCC sign extend. */
  441 + t0 = src;
  442 + t1 = dst;
  443 +
  444 + tmp = t0 * t1;
  445 + mof = tmp >> 32;
  446 + if (tmp == 0)
  447 + flags |= Z_FLAG;
  448 + else if (tmp >> 63)
  449 + flags |= N_FLAG;
  450 + if (mof)
  451 + flags |= V_FLAG;
  452 +
  453 + evaluate_flags_writeback(flags);
  454 + RETURN();
  455 +}
  456 +
  457 +void OPPROTO op_evaluate_flags_mcp(void)
  458 +{
  459 + uint32_t src;
  460 + uint32_t dst;
  461 + uint32_t res;
  462 + uint32_t flags = 0;
  463 +
  464 + src = env->cc_src;
  465 + dst = env->cc_dest;
  466 + res = env->cc_result;
  467 +
  468 + if ((res & 0x80000000L) != 0L)
  469 + {
  470 + flags |= N_FLAG;
  471 + if (((src & 0x80000000L) == 0L)
  472 + && ((dst & 0x80000000L) == 0L))
  473 + {
  474 + flags |= V_FLAG;
  475 + }
  476 + else if (((src & 0x80000000L) != 0L) &&
  477 + ((dst & 0x80000000L) != 0L))
  478 + {
  479 + flags |= R_FLAG;
  480 + }
  481 + }
  482 + else
  483 + {
  484 + if (res == 0L)
  485 + flags |= Z_FLAG;
  486 + if (((src & 0x80000000L) != 0L)
  487 + && ((dst & 0x80000000L) != 0L))
  488 + flags |= V_FLAG;
  489 + if ((dst & 0x80000000L) != 0L
  490 + || (src & 0x80000000L) != 0L)
  491 + flags |= R_FLAG;
  492 + }
  493 +
  494 + evaluate_flags_writeback(flags);
  495 + RETURN();
  496 +}
  497 +
  498 +void OPPROTO op_evaluate_flags_alu_4(void)
  499 +{
  500 + uint32_t src;
  501 + uint32_t dst;
  502 + uint32_t res;
  503 + uint32_t flags = 0;
  504 +
  505 + src = env->cc_src;
  506 + dst = env->cc_dest;
  507 + res = env->cc_result;
  508 +
  509 + if ((res & 0x80000000L) != 0L)
  510 + {
  511 + flags |= N_FLAG;
  512 + if (((src & 0x80000000L) == 0L)
  513 + && ((dst & 0x80000000L) == 0L))
  514 + {
  515 + flags |= V_FLAG;
  516 + }
  517 + else if (((src & 0x80000000L) != 0L) &&
  518 + ((dst & 0x80000000L) != 0L))
  519 + {
  520 + flags |= C_FLAG;
  521 + }
  522 + }
  523 + else
  524 + {
  525 + if (res == 0L)
  526 + flags |= Z_FLAG;
  527 + if (((src & 0x80000000L) != 0L)
  528 + && ((dst & 0x80000000L) != 0L))
  529 + flags |= V_FLAG;
  530 + if ((dst & 0x80000000L) != 0L
  531 + || (src & 0x80000000L) != 0L)
  532 + flags |= C_FLAG;
  533 + }
  534 +
  535 + if (env->cc_op == CC_OP_SUB
  536 + || env->cc_op == CC_OP_CMP) {
  537 + flags ^= C_FLAG;
  538 + }
  539 + evaluate_flags_writeback(flags);
  540 + RETURN();
  541 +}
  542 +
  543 +void OPPROTO op_evaluate_flags_move_4 (void)
  544 +{
  545 + uint32_t src;
  546 + uint32_t res;
  547 + uint32_t flags = 0;
  548 +
  549 + src = env->cc_src;
  550 + res = env->cc_result;
  551 +
  552 + if ((int32_t)res < 0)
  553 + flags |= N_FLAG;
  554 + else if (res == 0L)
  555 + flags |= Z_FLAG;
  556 +
  557 + evaluate_flags_writeback(flags);
  558 + RETURN();
  559 +}
  560 +void OPPROTO op_evaluate_flags_move_2 (void)
  561 +{
  562 + uint32_t src;
  563 + uint32_t flags = 0;
  564 + uint16_t res;
  565 +
  566 + src = env->cc_src;
  567 + res = env->cc_result;
  568 +
  569 + if ((int16_t)res < 0L)
  570 + flags |= N_FLAG;
  571 + else if (res == 0)
  572 + flags |= Z_FLAG;
  573 +
  574 + evaluate_flags_writeback(flags);
  575 + RETURN();
  576 +}
  577 +
  578 +/* TODO: This is expensive. We could split things up and only evaluate part of
  579 + CCR on a need to know basis. For now, we simply re-evaluate everything. */
  580 +void OPPROTO op_evaluate_flags (void)
  581 +{
  582 + uint32_t src;
  583 + uint32_t dst;
  584 + uint32_t res;
  585 + uint32_t flags = 0;
  586 +
  587 + src = env->cc_src;
  588 + dst = env->cc_dest;
  589 + res = env->cc_result;
  590 +
  591 +
  592 + /* Now, evaluate the flags. This stuff is based on
  593 + Per Zander's CRISv10 simulator. */
  594 + switch (env->cc_size)
  595 + {
  596 + case 1:
  597 + if ((res & 0x80L) != 0L)
  598 + {
  599 + flags |= N_FLAG;
  600 + if (((src & 0x80L) == 0L)
  601 + && ((dst & 0x80L) == 0L))
  602 + {
  603 + flags |= V_FLAG;
  604 + }
  605 + else if (((src & 0x80L) != 0L)
  606 + && ((dst & 0x80L) != 0L))
  607 + {
  608 + flags |= C_FLAG;
  609 + }
  610 + }
  611 + else
  612 + {
  613 + if ((res & 0xFFL) == 0L)
  614 + {
  615 + flags |= Z_FLAG;
  616 + }
  617 + if (((src & 0x80L) != 0L)
  618 + && ((dst & 0x80L) != 0L))
  619 + {
  620 + flags |= V_FLAG;
  621 + }
  622 + if ((dst & 0x80L) != 0L
  623 + || (src & 0x80L) != 0L)
  624 + {
  625 + flags |= C_FLAG;
  626 + }
  627 + }
  628 + break;
  629 + case 2:
  630 + if ((res & 0x8000L) != 0L)
  631 + {
  632 + flags |= N_FLAG;
  633 + if (((src & 0x8000L) == 0L)
  634 + && ((dst & 0x8000L) == 0L))
  635 + {
  636 + flags |= V_FLAG;
  637 + }
  638 + else if (((src & 0x8000L) != 0L)
  639 + && ((dst & 0x8000L) != 0L))
  640 + {
  641 + flags |= C_FLAG;
  642 + }
  643 + }
  644 + else
  645 + {
  646 + if ((res & 0xFFFFL) == 0L)
  647 + {
  648 + flags |= Z_FLAG;
  649 + }
  650 + if (((src & 0x8000L) != 0L)
  651 + && ((dst & 0x8000L) != 0L))
  652 + {
  653 + flags |= V_FLAG;
  654 + }
  655 + if ((dst & 0x8000L) != 0L
  656 + || (src & 0x8000L) != 0L)
  657 + {
  658 + flags |= C_FLAG;
  659 + }
  660 + }
  661 + break;
  662 + case 4:
  663 + if ((res & 0x80000000L) != 0L)
  664 + {
  665 + flags |= N_FLAG;
  666 + if (((src & 0x80000000L) == 0L)
  667 + && ((dst & 0x80000000L) == 0L))
  668 + {
  669 + flags |= V_FLAG;
  670 + }
  671 + else if (((src & 0x80000000L) != 0L) &&
  672 + ((dst & 0x80000000L) != 0L))
  673 + {
  674 + flags |= C_FLAG;
  675 + }
  676 + }
  677 + else
  678 + {
  679 + if (res == 0L)
  680 + flags |= Z_FLAG;
  681 + if (((src & 0x80000000L) != 0L)
  682 + && ((dst & 0x80000000L) != 0L))
  683 + flags |= V_FLAG;
  684 + if ((dst & 0x80000000L) != 0L
  685 + || (src & 0x80000000L) != 0L)
  686 + flags |= C_FLAG;
  687 + }
  688 + break;
  689 + default:
  690 + break;
  691 + }
  692 +
  693 + if (env->cc_op == CC_OP_SUB
  694 + || env->cc_op == CC_OP_CMP) {
  695 + flags ^= C_FLAG;
  696 + }
  697 + evaluate_flags_writeback(flags);
  698 + RETURN();
  699 +}
  700 +
  701 +void OPPROTO op_extb_T0_T0 (void)
  702 +{
  703 + T0 = ((int8_t)T0);
  704 + RETURN();
  705 +}
  706 +void OPPROTO op_extb_T1_T0 (void)
  707 +{
  708 + T1 = ((int8_t)T0);
  709 + RETURN();
  710 +}
  711 +void OPPROTO op_extb_T1_T1 (void)
  712 +{
  713 + T1 = ((int8_t)T1);
  714 + RETURN();
  715 +}
  716 +void OPPROTO op_zextb_T0_T0 (void)
  717 +{
  718 + T0 = ((uint8_t)T0);
  719 + RETURN();
  720 +}
  721 +void OPPROTO op_zextb_T1_T0 (void)
  722 +{
  723 + T1 = ((uint8_t)T0);
  724 + RETURN();
  725 +}
  726 +void OPPROTO op_zextb_T1_T1 (void)
  727 +{
  728 + T1 = ((uint8_t)T1);
  729 + RETURN();
  730 +}
  731 +void OPPROTO op_extw_T0_T0 (void)
  732 +{
  733 + T0 = ((int16_t)T0);
  734 + RETURN();
  735 +}
  736 +void OPPROTO op_extw_T1_T0 (void)
  737 +{
  738 + T1 = ((int16_t)T0);
  739 + RETURN();
  740 +}
  741 +void OPPROTO op_extw_T1_T1 (void)
  742 +{
  743 + T1 = ((int16_t)T1);
  744 + RETURN();
  745 +}
  746 +
  747 +void OPPROTO op_zextw_T0_T0 (void)
  748 +{
  749 + T0 = ((uint16_t)T0);
  750 + RETURN();
  751 +}
  752 +void OPPROTO op_zextw_T1_T0 (void)
  753 +{
  754 + T1 = ((uint16_t)T0);
  755 + RETURN();
  756 +}
  757 +
  758 +void OPPROTO op_zextw_T1_T1 (void)
  759 +{
  760 + T1 = ((uint16_t)T1);
  761 + RETURN();
  762 +}
  763 +
  764 +void OPPROTO op_movl_T0_im (void)
  765 +{
  766 + T0 = PARAM1;
  767 + RETURN();
  768 +}
  769 +void OPPROTO op_movl_T1_im (void)
  770 +{
  771 + T1 = PARAM1;
  772 + RETURN();
  773 +}
  774 +
  775 +void OPPROTO op_addl_T0_im (void)
  776 +{
  777 + T0 += PARAM1;
  778 + RETURN();
  779 +}
  780 +
  781 +void OPPROTO op_addl_T1_im (void)
  782 +{
  783 + T1 += PARAM1;
  784 + RETURN();
  785 +
  786 +}
  787 +void OPPROTO op_subl_T0_im (void)
  788 +{
  789 + T0 -= PARAM1;
  790 + RETURN();
  791 +}
  792 +
  793 +void OPPROTO op_addxl_T0_C (void)
  794 +{
  795 + if (env->pregs[SR_CCS] & X_FLAG)
  796 + T0 += !!(env->pregs[SR_CCS] & C_FLAG);
  797 + RETURN();
  798 +}
  799 +void OPPROTO op_subxl_T0_C (void)
  800 +{
  801 + if (env->pregs[SR_CCS] & X_FLAG)
  802 + T0 -= !!(env->pregs[SR_CCS] & C_FLAG);
  803 + RETURN();
  804 +}
  805 +void OPPROTO op_addl_T0_C (void)
  806 +{
  807 + T0 += !!(env->pregs[SR_CCS] & C_FLAG);
  808 + RETURN();
  809 +}
  810 +void OPPROTO op_addl_T0_R (void)
  811 +{
  812 + T0 += !!(env->pregs[SR_CCS] & R_FLAG);
  813 + RETURN();
  814 +}
  815 +
  816 +void OPPROTO op_clr_R (void)
  817 +{
  818 + env->pregs[SR_CCS] &= ~R_FLAG;
  819 + RETURN();
  820 +}
  821 +
  822 +
  823 +void OPPROTO op_andl_T0_im (void)
  824 +{
  825 + T0 &= PARAM1;
  826 + RETURN();
  827 +}
  828 +
  829 +void OPPROTO op_andl_T1_im (void)
  830 +{
  831 + T1 &= PARAM1;
  832 + RETURN();
  833 +}
  834 +
  835 +void OPPROTO op_movl_T0_T1 (void)
  836 +{
  837 + T0 = T1;
  838 + RETURN();
  839 +}
  840 +
  841 +void OPPROTO op_swp_T0_T1 (void)
  842 +{
  843 + T0 ^= T1;
  844 + T1 ^= T0;
  845 + T0 ^= T1;
  846 + RETURN();
  847 +}
  848 +
  849 +void OPPROTO op_movl_T1_T0 (void)
  850 +{
  851 + T1 = T0;
  852 + RETURN();
  853 +}
  854 +
  855 +void OPPROTO op_movl_pc_T0 (void)
  856 +{
  857 + env->pc = T0;
  858 + RETURN();
  859 +}
  860 +
  861 +void OPPROTO op_movl_T0_0 (void)
  862 +{
  863 + T0 = 0;
  864 + RETURN();
  865 +}
  866 +
  867 +void OPPROTO op_addl_T0_T1 (void)
  868 +{
  869 + T0 += T1;
  870 + RETURN();
  871 +}
  872 +
  873 +void OPPROTO op_subl_T0_T1 (void)
  874 +{
  875 + T0 -= T1;
  876 + RETURN();
  877 +}
  878 +
  879 +void OPPROTO op_absl_T1_T1 (void)
  880 +{
  881 + int32_t st = T1;
  882 +
  883 + T1 = st < 0 ? -st : st;
  884 + RETURN();
  885 +}
  886 +
  887 +void OPPROTO op_muls_T0_T1 (void)
  888 +{
  889 + int64_t tmp, t0 ,t1;
  890 +
  891 + /* cast into signed values to make GCC sign extend these babies. */
  892 + t0 = (int32_t)T0;
  893 + t1 = (int32_t)T1;
  894 +
  895 + tmp = t0 * t1;
  896 + T0 = tmp & 0xffffffff;
  897 + env->pregs[REG_MOF] = tmp >> 32;
  898 + RETURN();
  899 +}
  900 +
  901 +void OPPROTO op_mulu_T0_T1 (void)
  902 +{
  903 + uint64_t tmp, t0 ,t1;
  904 + t0 = T0;
  905 + t1 = T1;
  906 +
  907 + tmp = t0 * t1;
  908 + T0 = tmp & 0xffffffff;
  909 + env->pregs[REG_MOF] = tmp >> 32;
  910 + RETURN();
  911 +}
  912 +
  913 +void OPPROTO op_dstep_T0_T1 (void)
  914 +{
  915 + T0 <<= 1;
  916 + if (T0 >= T1)
  917 + T0 -= T1;
  918 + RETURN();
  919 +}
  920 +
  921 +void OPPROTO op_orl_T0_T1 (void)
  922 +{
  923 + T0 |= T1;
  924 + RETURN();
  925 +}
  926 +
  927 +void OPPROTO op_andl_T0_T1 (void)
  928 +{
  929 + T0 &= T1;
  930 + RETURN();
  931 +}
  932 +
  933 +void OPPROTO op_xorl_T0_T1 (void)
  934 +{
  935 + T0 ^= T1;
  936 + RETURN();
  937 +}
  938 +
  939 +void OPPROTO op_lsll_T0_T1 (void)
  940 +{
  941 + int s = T1;
  942 + if (s > 31)
  943 + T0 = 0;
  944 + else
  945 + T0 <<= s;
  946 + RETURN();
  947 +}
  948 +
  949 +void OPPROTO op_lsll_T0_im (void)
  950 +{
  951 + T0 <<= PARAM1;
  952 + RETURN();
  953 +}
  954 +
  955 +void OPPROTO op_lsrl_T0_T1 (void)
  956 +{
  957 + int s = T1;
  958 + if (s > 31)
  959 + T0 = 0;
  960 + else
  961 + T0 >>= s;
  962 + RETURN();
  963 +}
  964 +
  965 +/* Rely on GCC emitting an arithmetic shift for signed right shifts. */
  966 +void OPPROTO op_asrl_T0_T1 (void)
  967 +{
  968 + int s = T1;
  969 + if (s > 31)
  970 + T0 = T0 & 0x80000000 ? -1 : 0;
  971 + else
  972 + T0 = (int32_t)T0 >> s;
  973 + RETURN();
  974 +}
  975 +
  976 +void OPPROTO op_btst_T0_T1 (void)
  977 +{
  978 + /* FIXME: clean this up. */
  979 +
  980 + /* des ref:
  981 + The N flag is set according to the selected bit in the dest reg.
  982 + The Z flag is set if the selected bit and all bits to the right are
  983 + zero.
  984 + The destination reg is not affected.*/
  985 + unsigned int fz, sbit, bset, mask, masked_t0;
  986 +
  987 + sbit = T1 & 31;
  988 + bset = !!(T0 & (1 << sbit));
  989 + mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
  990 + masked_t0 = T0 & mask;
  991 + fz = !(masked_t0 | bset);
  992 + /* Set the N and Z flags accordingly. */
  993 + T0 = (bset << 3) | (fz << 2);
  994 + RETURN();
  995 +}
  996 +
  997 +void OPPROTO op_bound_T0_T1 (void)
  998 +{
  999 + if (T0 > T1)
  1000 + T0 = T1;
  1001 + RETURN();
  1002 +}
  1003 +
  1004 +void OPPROTO op_lz_T0_T1 (void)
  1005 +{
  1006 + if (T1 == 0)
  1007 + T0 = 32;
  1008 + else
  1009 + T0 = __builtin_clz(T1);
  1010 + RETURN();
  1011 +}
  1012 +
  1013 +void OPPROTO op_negl_T0_T1 (void)
  1014 +{
  1015 + T0 = -T1;
  1016 + RETURN();
  1017 +}
  1018 +
  1019 +void OPPROTO op_negl_T1_T1 (void)
  1020 +{
  1021 + T1 = -T1;
  1022 + RETURN();
  1023 +}
  1024 +
  1025 +void OPPROTO op_not_T0_T0 (void)
  1026 +{
  1027 + T0 = ~(T0);
  1028 + RETURN();
  1029 +}
  1030 +void OPPROTO op_not_T1_T1 (void)
  1031 +{
  1032 + T1 = ~(T1);
  1033 + RETURN();
  1034 +}
  1035 +
  1036 +void OPPROTO op_swapw_T0_T0 (void)
  1037 +{
  1038 + T0 = (T0 << 16) | ((T0 >> 16));
  1039 + RETURN();
  1040 +}
  1041 +
  1042 +void OPPROTO op_swapb_T0_T0 (void)
  1043 +{
  1044 + T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff);
  1045 + RETURN();
  1046 +}
  1047 +
  1048 +void OPPROTO op_swapr_T0_T0 (void)
  1049 +{
  1050 + T0 = (((T0 << 7) & 0x80808080) |
  1051 + ((T0 << 5) & 0x40404040) |
  1052 + ((T0 << 3) & 0x20202020) |
  1053 + ((T0 << 1) & 0x10101010) |
  1054 + ((T0 >> 1) & 0x08080808) |
  1055 + ((T0 >> 3) & 0x04040404) |
  1056 + ((T0 >> 5) & 0x02020202) |
  1057 + ((T0 >> 7) & 0x01010101));
  1058 + RETURN();
  1059 +}
  1060 +
  1061 +void OPPROTO op_tst_cc_eq (void) {
  1062 + uint32_t flags = env->pregs[SR_CCS];
  1063 + int z_set;
  1064 +
  1065 + z_set = !!(flags & Z_FLAG);
  1066 + T0 = z_set;
  1067 + RETURN();
  1068 +}
  1069 +
  1070 +void OPPROTO op_tst_cc_eq_fast (void) {
  1071 + T0 = !(env->cc_result);
  1072 + RETURN();
  1073 +}
  1074 +
  1075 +void OPPROTO op_tst_cc_ne (void) {
  1076 + uint32_t flags = env->pregs[SR_CCS];
  1077 + int z_set;
  1078 +
  1079 + z_set = !!(flags & Z_FLAG);
  1080 + T0 = !z_set;
  1081 + RETURN();
  1082 +}
  1083 +void OPPROTO op_tst_cc_ne_fast (void) {
  1084 + T0 = !!(env->cc_result);
  1085 + RETURN();
  1086 +}
  1087 +
  1088 +void OPPROTO op_tst_cc_cc (void) {
  1089 + uint32_t flags = env->pregs[SR_CCS];
  1090 + int c_set;
  1091 +
  1092 + c_set = !!(flags & C_FLAG);
  1093 + T0 = !c_set;
  1094 + RETURN();
  1095 +}
  1096 +void OPPROTO op_tst_cc_cs (void) {
  1097 + uint32_t flags = env->pregs[SR_CCS];
  1098 + int c_set;
  1099 +
  1100 + c_set = !!(flags & C_FLAG);
  1101 + T0 = c_set;
  1102 + RETURN();
  1103 +}
  1104 +
  1105 +void OPPROTO op_tst_cc_vc (void) {
  1106 + uint32_t flags = env->pregs[SR_CCS];
  1107 + int v_set;
  1108 +
  1109 + v_set = !!(flags & V_FLAG);
  1110 + T0 = !v_set;
  1111 + RETURN();
  1112 +}
  1113 +void OPPROTO op_tst_cc_vs (void) {
  1114 + uint32_t flags = env->pregs[SR_CCS];
  1115 + int v_set;
  1116 +
  1117 + v_set = !!(flags & V_FLAG);
  1118 + T0 = v_set;
  1119 + RETURN();
  1120 +}
  1121 +void OPPROTO op_tst_cc_pl (void) {
  1122 + uint32_t flags = env->pregs[SR_CCS];
  1123 + int n_set;
  1124 +
  1125 + n_set = !!(flags & N_FLAG);
  1126 + T0 = !n_set;
  1127 + RETURN();
  1128 +}
  1129 +void OPPROTO op_tst_cc_pl_fast (void) {
  1130 + T0 = ((int32_t)env->cc_result) >= 0;
  1131 + RETURN();
  1132 +}
  1133 +
  1134 +void OPPROTO op_tst_cc_mi (void) {
  1135 + uint32_t flags = env->pregs[SR_CCS];
  1136 + int n_set;
  1137 +
  1138 + n_set = !!(flags & N_FLAG);
  1139 + T0 = n_set;
  1140 + RETURN();
  1141 +}
  1142 +void OPPROTO op_tst_cc_mi_fast (void) {
  1143 + T0 = ((int32_t)env->cc_result) < 0;
  1144 + RETURN();
  1145 +}
  1146 +
  1147 +void OPPROTO op_tst_cc_ls (void) {
  1148 + uint32_t flags = env->pregs[SR_CCS];
  1149 + int c_set;
  1150 + int z_set;
  1151 +
  1152 + c_set = !!(flags & C_FLAG);
  1153 + z_set = !!(flags & Z_FLAG);
  1154 + T0 = c_set || z_set;
  1155 + RETURN();
  1156 +}
  1157 +void OPPROTO op_tst_cc_hi (void) {
  1158 + uint32_t flags = env->pregs[SR_CCS];
  1159 + int z_set;
  1160 + int c_set;
  1161 +
  1162 + z_set = !!(flags & Z_FLAG);
  1163 + c_set = !!(flags & C_FLAG);
  1164 + T0 = !c_set && !z_set;
  1165 + RETURN();
  1166 +
  1167 +}
  1168 +
  1169 +void OPPROTO op_tst_cc_ge (void) {
  1170 + uint32_t flags = env->pregs[SR_CCS];
  1171 + int n_set;
  1172 + int v_set;
  1173 +
  1174 + n_set = !!(flags & N_FLAG);
  1175 + v_set = !!(flags & V_FLAG);
  1176 + T0 = (n_set && v_set) || (!n_set && !v_set);
  1177 + RETURN();
  1178 +}
  1179 +
  1180 +void OPPROTO op_tst_cc_ge_fast (void) {
  1181 + T0 = ((int32_t)env->cc_src < (int32_t)env->cc_dest);
  1182 + RETURN();
  1183 +}
  1184 +
  1185 +void OPPROTO op_tst_cc_lt (void) {
  1186 + uint32_t flags = env->pregs[SR_CCS];
  1187 + int n_set;
  1188 + int v_set;
  1189 +
  1190 + n_set = !!(flags & N_FLAG);
  1191 + v_set = !!(flags & V_FLAG);
  1192 + T0 = (n_set && !v_set) || (!n_set && v_set);
  1193 + RETURN();
  1194 +}
  1195 +
  1196 +void OPPROTO op_tst_cc_gt (void) {
  1197 + uint32_t flags = env->pregs[SR_CCS];
  1198 + int n_set;
  1199 + int v_set;
  1200 + int z_set;
  1201 +
  1202 + n_set = !!(flags & N_FLAG);
  1203 + v_set = !!(flags & V_FLAG);
  1204 + z_set = !!(flags & Z_FLAG);
  1205 + T0 = (n_set && v_set && !z_set)
  1206 + || (!n_set && !v_set && !z_set);
  1207 + RETURN();
  1208 +}
  1209 +
  1210 +void OPPROTO op_tst_cc_le (void) {
  1211 + uint32_t flags = env->pregs[SR_CCS];
  1212 + int n_set;
  1213 + int v_set;
  1214 + int z_set;
  1215 +
  1216 + n_set = !!(flags & N_FLAG);
  1217 + v_set = !!(flags & V_FLAG);
  1218 + z_set = !!(flags & Z_FLAG);
  1219 + T0 = z_set || (n_set && !v_set) || (!n_set && v_set);
  1220 + RETURN();
  1221 +}
  1222 +
  1223 +void OPPROTO op_tst_cc_p (void) {
  1224 + uint32_t flags = env->pregs[SR_CCS];
  1225 + int p_set;
  1226 +
  1227 + p_set = !!(flags & P_FLAG);
  1228 + T0 = p_set;
  1229 + RETURN();
  1230 +}
  1231 +
  1232 +/* Evaluate the if the branch should be taken or not. Needs to be done in
  1233 + the original sequence. The acutal branch is rescheduled to right after the
  1234 + delay-slot. */
  1235 +void OPPROTO op_evaluate_bcc (void)
  1236 +{
  1237 + env->btaken = T0;
  1238 + RETURN();
  1239 +}
  1240 +
  1241 +/* this one is used on every alu op, optimize it!. */
  1242 +void OPPROTO op_goto_if_not_x (void)
  1243 +{
  1244 + if (env->pregs[SR_CCS] & X_FLAG)
  1245 + GOTO_LABEL_PARAM(1);
  1246 + RETURN();
  1247 +}
  1248 +
  1249 +void OPPROTO op_cc_jmp (void)
  1250 +{
  1251 + if (env->btaken)
  1252 + env->pc = PARAM1;
  1253 + else
  1254 + env->pc = PARAM2;
  1255 + RETURN();
  1256 +}
  1257 +
  1258 +void OPPROTO op_cc_ngoto (void)
  1259 +{
  1260 + if (!env->btaken)
  1261 + GOTO_LABEL_PARAM(1);
  1262 + RETURN();
  1263 +}
  1264 +
  1265 +void OPPROTO op_movl_btarget_T0 (void)
  1266 +{
  1267 + env->btarget = T0;
  1268 + RETURN();
  1269 +}
  1270 +
  1271 +void OPPROTO op_jmp (void)
  1272 +{
  1273 + env->pc = env->btarget;
  1274 + RETURN();
  1275 +}
  1276 +
  1277 +/* Load and store */
  1278 +#define MEMSUFFIX _raw
  1279 +#include "op_mem.c"
  1280 +#undef MEMSUFFIX
  1281 +#if !defined(CONFIG_USER_ONLY)
  1282 +#define MEMSUFFIX _user
  1283 +#include "op_mem.c"
  1284 +#undef MEMSUFFIX
  1285 +
  1286 +#define MEMSUFFIX _kernel
  1287 +#include "op_mem.c"
  1288 +#undef MEMSUFFIX
  1289 +#endif
... ...