Revision c596defd

b/tcg/ppc/tcg-target.c
282 282

  
283 283
#define RLWINM OPCD(21)
284 284

  
285
#define BCLR   XO19(16)
285
#define BCLR   XO19( 16)
286 286
#define BCCTR  XO19(528)
287 287
#define CRAND  XO19(257)
288
#define CRANDC XO19(129)
289
#define CRNAND XO19(225)
290
#define CROR   XO19(449)
288 291

  
289 292
#define EXTSB  XO31(954)
290 293
#define EXTSH  XO31(922)
......
870 873
    ppc_addi (s, reg, reg, val);
871 874
}
872 875

  
873
static void tcg_out_brcond(TCGContext *s, int cond,
874
                           TCGArg arg1, TCGArg arg2, int const_arg2,
875
                           int label_index)
876
static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
877
                         int const_arg2, int cr)
876 878
{
877
    TCGLabel *l = &s->labels[label_index];
878 879
    int imm;
879 880
    uint32_t op;
880 881

  
......
930 931
    default:
931 932
        tcg_abort ();
932 933
    }
933
    op |= BF (7);
934
    op |= BF (cr);
934 935

  
935 936
    if (imm)
936 937
        tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
......
943 944
            tcg_out32 (s, op | RA (arg1) | RB (arg2));
944 945
    }
945 946

  
947
}
948

  
949
static void tcg_out_bc (TCGContext *s, int bc, int label_index)
950
{
951
    TCGLabel *l = &s->labels[label_index];
952

  
946 953
    if (l->has_value)
947
        tcg_out32 (s, tcg_to_bc[cond] | reloc_pc14_val (s->code_ptr,
948
                                                        l->u.value));
954
        tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
949 955
    else {
950 956
        uint16_t val = *(uint16_t *) &s->code_ptr[2];
951 957

  
952 958
        /* Thanks to Andrzej Zaborowski */
953
        tcg_out32 (s, tcg_to_bc[cond] | (val & 0xfffc));
959
        tcg_out32 (s, bc | (val & 0xfffc));
954 960
        tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
955 961
    }
956 962
}
957 963

  
958
/* brcond2 is taken verbatim from i386 tcg-target */
964
static void tcg_out_brcond (TCGContext *s, int cond,
965
                            TCGArg arg1, TCGArg arg2, int const_arg2,
966
                            int label_index)
967
{
968
    tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
969
    tcg_out_bc (s, tcg_to_bc[cond], label_index);
970
}
971

  
959 972
/* XXX: we implement it at the target level to avoid having to
960 973
   handle cross basic blocks temporaries */
961
static void tcg_out_brcond2(TCGContext *s,
962
                            const TCGArg *args, const int *const_args)
974
static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
975
                             const int *const_args)
963 976
{
964
    int label_next;
965
    label_next = gen_new_label();
966
    switch(args[4]) {
977
    int cond = args[4], label_index = args[5], op;
978
    struct { int bit1; int bit2; int cond2; } bits[] = {
979
        [TCG_COND_LT ] = { CR_LT, CR_LT, TCG_COND_LT  },
980
        [TCG_COND_LE ] = { CR_LT, CR_GT, TCG_COND_LT  },
981
        [TCG_COND_GT ] = { CR_GT, CR_GT, TCG_COND_GT  },
982
        [TCG_COND_GE ] = { CR_GT, CR_LT, TCG_COND_GT  },
983
        [TCG_COND_LTU] = { CR_LT, CR_LT, TCG_COND_LTU },
984
        [TCG_COND_LEU] = { CR_LT, CR_GT, TCG_COND_LTU },
985
        [TCG_COND_GTU] = { CR_GT, CR_GT, TCG_COND_GTU },
986
        [TCG_COND_GEU] = { CR_GT, CR_LT, TCG_COND_GTU },
987
    }, *b = &bits[cond];
988

  
989
    switch (cond) {
967 990
    case TCG_COND_EQ:
968
        tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], label_next);
969
        tcg_out_brcond(s, TCG_COND_EQ, args[1], args[3], const_args[3], args[5]);
991
        tcg_out_cmp (s, TCG_COND_EQ, args[0], args[2], const_args[2], 6);
992
        tcg_out_cmp (s, TCG_COND_EQ, args[1], args[3], const_args[3], 7);
993
        tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
970 994
        break;
971 995
    case TCG_COND_NE:
972
        tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], args[5]);
973
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], args[5]);
996
        tcg_out_cmp (s, TCG_COND_NE, args[0], args[2], const_args[2], 6);
997
        tcg_out_cmp (s, TCG_COND_NE, args[1], args[3], const_args[3], 7);
998
        tcg_out32 (s, CRNAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));
974 999
        break;
975 1000
    case TCG_COND_LT:
976
        tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]);
977
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
978
        tcg_out_brcond(s, TCG_COND_LT, args[0], args[2], const_args[2], args[5]);
979
        break;
980 1001
    case TCG_COND_LE:
981
        tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]);
982
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
983
        tcg_out_brcond(s, TCG_COND_LE, args[0], args[2], const_args[2], args[5]);
984
        break;
985 1002
    case TCG_COND_GT:
986
        tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]);
987
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
988
        tcg_out_brcond(s, TCG_COND_GT, args[0], args[2], const_args[2], args[5]);
989
        break;
990 1003
    case TCG_COND_GE:
991
        tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]);
992
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
993
        tcg_out_brcond(s, TCG_COND_GE, args[0], args[2], const_args[2], args[5]);
994
        break;
995 1004
    case TCG_COND_LTU:
996
        tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]);
997
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
998
        tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], args[5]);
999
        break;
1000 1005
    case TCG_COND_LEU:
1001
        tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]);
1002
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
1003
        tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]);
1004
        break;
1005 1006
    case TCG_COND_GTU:
1006
        tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]);
1007
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
1008
        tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]);
1009
        break;
1010 1007
    case TCG_COND_GEU:
1011
        tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]);
1012
        tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next);
1013
        tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]);
1008
        op = (b->bit1 != b->bit2) ? CRANDC : CRAND;
1009
        tcg_out_cmp (s, b->cond2, args[1], args[3], const_args[3], 5);
1010
        tcg_out_cmp (s, TCG_COND_EQ, args[1], args[3], const_args[3], 6);
1011
        tcg_out_cmp (s, cond, args[0], args[2], const_args[2], 7);
1012
        tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, b->bit2));
1013
        tcg_out32 (s, CROR | BT (7, CR_EQ) | BA (5, b->bit1) | BB (7, CR_EQ));
1014 1014
        break;
1015 1015
    default:
1016 1016
        tcg_abort();
1017 1017
    }
1018
    tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr);
1018

  
1019
    tcg_out_bc (s, (BC | BI (7, CR_EQ) | BO_COND_TRUE), label_index);
1019 1020
}
1020 1021

  
1021 1022
static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,

Also available in: Unified diff