Revision fa4fbfb9 tcg/ppc/tcg-target.c

b/tcg/ppc/tcg-target.c
23 23
 */
24 24

  
25 25
static uint8_t *tb_ret_addr;
26
static uint8_t *udiv_addr;
27
static uint8_t *div_addr;
26 28

  
27 29
#define FAST_PATH
28 30
#if TARGET_PHYS_ADDR_BITS <= 32
......
118 120
};
119 121

  
120 122
static const int tcg_target_callee_save_regs[] = {
121
    TCG_REG_R13,                /* sould r13 be saved? */
123
    TCG_REG_R13,                /* should r13 be saved? */
122 124
    TCG_REG_R14,
123 125
    TCG_REG_R15,
124 126
    TCG_REG_R16,
......
135 137
    TCG_REG_R31
136 138
};
137 139

  
140
static const int div_save_regs[] = {
141
    TCG_REG_R4,
142
    TCG_REG_R5,
143
    TCG_REG_R7,
144
    TCG_REG_R8,
145
    TCG_REG_R9,
146
    TCG_REG_R10,
147
    TCG_REG_R11,
148
    TCG_REG_R12,
149
    TCG_REG_R13,                /* should r13 be saved? */
150
    TCG_REG_R24,
151
    TCG_REG_R25,
152
    TCG_REG_R26,
153
    TCG_REG_R27,
154
};
155

  
138 156
static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
139 157
{
140 158
    tcg_target_long disp;
......
799 817
#endif
800 818
}
801 819

  
820
static uint64_t ppc_udiv_helper (uint64_t a, uint32_t b)
821
{
822
    uint64_t rem, quo;
823
    quo = a / b;
824
    rem = a % b;
825
    return (rem << 32) | (uint32_t) quo;
826
}
827

  
828
static uint64_t ppc_div_helper (int64_t a, int32_t b)
829
{
830
    int64_t rem, quo;
831
    quo = a / b;
832
    rem = a % b;
833
    return (rem << 32) | (uint32_t) quo;
834
}
835

  
802 836
void tcg_target_qemu_prologue (TCGContext *s)
803 837
{
804
    int i, frame_size;
838
    int i, j, frame_size;
805 839

  
806 840
    frame_size = 0
807 841
        + 4                     /* back chain */
......
837 871
    tcg_out32 (s, MTSPR | RS (0) | LR);
838 872
    tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
839 873
    tcg_out32 (s, BCLR | BO_ALWAYS);
874

  
875
    /* div trampolines */
876
    for (j = 0; j < 2; ++j) {
877
        tcg_target_long target;
878

  
879
        frame_size = 8 + ARRAY_SIZE (div_save_regs) * 4;
880
        frame_size = (frame_size + 15) & ~15;
881

  
882
        if (j == 0) {
883
            target = (tcg_target_long) ppc_udiv_helper;
884
            udiv_addr = s->code_ptr;
885
        }
886
        else {
887
            target = (tcg_target_long) ppc_div_helper;
888
            div_addr = s->code_ptr;
889
        }
890

  
891
        tcg_out32 (s, MFSPR | RT (0) | LR);
892
        tcg_out32 (s, STWU | RS (1) | RA (1) | (-frame_size & 0xffff));
893
        for (i = 0; i < ARRAY_SIZE (div_save_regs); ++i)
894
            tcg_out32 (s, (STW
895
                           | RS (div_save_regs[i])
896
                           | RA (1)
897
                           | (i * 4 + 8)
898
                           )
899
                );
900
        tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size - 4));
901
        tcg_out_mov (s, 4, 6);
902
        tcg_out_b (s, LK, target);
903
        tcg_out_mov (s, 6, 4);
904

  
905
        for (i = 0; i < ARRAY_SIZE (div_save_regs); ++i)
906
            tcg_out32 (s, (LWZ
907
                           | RT (div_save_regs[i])
908
                           | RA (1)
909
                           | (i * 4 + 8)
910
                           )
911
                );
912
        tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size - 4));
913
        tcg_out32 (s, MTSPR | RS (0) | LR);
914
        tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
915
        tcg_out32 (s, BCLR | BO_ALWAYS);
916
    }
840 917
}
841 918

  
842 919
static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
......
1018 1095
    tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr);
1019 1096
}
1020 1097

  
1021
static uint64_t __attribute ((used)) ppc_udiv_helper (uint64_t a, uint32_t b)
1022
{
1023
    uint64_t rem, quo;
1024
    quo = a / b;
1025
    rem = a % b;
1026
    return (rem << 32) | (uint32_t) quo;
1027
}
1028

  
1029
static uint64_t __attribute ((used)) ppc_div_helper (int64_t a, int32_t b)
1030
{
1031
    int64_t rem, quo;
1032
    quo = a / b;
1033
    rem = a % b;
1034
    return (rem << 32) | (uint32_t) quo;
1035
}
1036

  
1037
#define MAKE_TRAMPOLINE(name)                   \
1038
extern void name##_trampoline (void);           \
1039
asm (#name "_trampoline:\n"                     \
1040
     " mflr 0\n"                                \
1041
     " addi 1,1,-112\n"                         \
1042
     " mr   4,6\n"                              \
1043
     " stmw 7,0(1)\n"                           \
1044
     " stw  0,108(0)\n"                         \
1045
     " bl   ppc_" #name "_helper\n"             \
1046
     " lmw  7,0(1)\n"                           \
1047
     " lwz  0,108(0)\n"                         \
1048
     " addi 1,1,112\n"                          \
1049
     " mtlr 0\n"                                \
1050
     " blr\n"                                   \
1051
    )
1052

  
1053
MAKE_TRAMPOLINE (div);
1054
MAKE_TRAMPOLINE (udiv);
1055

  
1056 1098
static void tcg_out_div2 (TCGContext *s, int uns)
1057 1099
{
1058 1100
    void *label1_ptr, *label2_ptr;
......
1067 1109
    label1_ptr = s->code_ptr;
1068 1110
    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
1069 1111

  
1070
    tcg_out_b (s, LK, (tcg_target_long) (uns ? udiv_trampoline : div_trampoline));
1112
    tcg_out_b (s, LK, (tcg_target_long) (uns ? udiv_addr : div_addr));
1071 1113

  
1072 1114
    label2_ptr = s->code_ptr;
1073 1115
    tcg_out32 (s, B);

Also available in: Unified diff