📄 h8300.c
字号:
0 },/* SHIFT_ASHIFTRT */ { "rotl\t%X0", "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0", 0 } },/* H8/300H */ {/* SHIFT_ASHIFT */ { "rotr.b\t%X0", "rotr.w\t%T0", "rotr.l\t%S0" },/* SHIFT_LSHIFTRT */ { "rotl.b\t%X0", "rotl.w\t%T0", "rotl.l\t%S0" },/* SHIFT_ASHIFTRT */ { "rotl.b\t%X0", "rotl.w\t%T0", "rotl.l\t%S0" } }};static const char *const rotate_two[3][3] ={/* SHIFT_ASHIFT */ { "rotr.b\t#2,%X0", "rotr.w\t#2,%T0", "rotr.l\t#2,%S0" },/* SHIFT_LSHIFTRT */ { "rotl.b\t#2,%X0", "rotl.w\t#2,%T0", "rotl.l\t#2,%S0" },/* SHIFT_ASHIFTRT */ { "rotl.b\t#2,%X0", "rotl.w\t#2,%T0", "rotl.l\t#2,%S0" }};/* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best algorithm for doing the shift. The assembler code is stored in ASSEMBLER. We don't achieve maximum efficiency in all cases, but the hooks are here to do so. For now we just use lots of switch statements. Since we don't even come close to supporting all the cases, this is simplest. If this function ever gets too big, perhaps resort to a more table based lookup. Of course, at this point you may just wish to do it all in rtl. WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of 1,2,3,4 will be inlined (1,2 for SI). */static enum shift_algget_shift_alg (cpu, shift_type, mode, count, assembler_p, assembler2_p, cc_valid_p) enum attr_cpu cpu; enum shift_type shift_type; enum machine_mode mode; int count; const char **assembler_p; const char **assembler2_p; int *cc_valid_p;{ /* The default is to loop. */ enum shift_alg alg = SHIFT_LOOP; enum shift_mode shift_mode; /* We don't handle negative shifts or shifts greater than the word size, they should have been handled already. */ if (count < 0 || count > GET_MODE_BITSIZE (mode)) abort (); switch (mode) { case QImode: shift_mode = QIshift; break; case HImode: shift_mode = HIshift; break; case SImode: shift_mode = SIshift; break; default: abort (); } /* Assume either SHIFT_LOOP or SHIFT_INLINE. It is up to the caller to know that looping clobbers cc. */ *assembler_p = shift_one[cpu][shift_type][shift_mode].assembler; if (TARGET_H8300S) *assembler2_p = shift_two[shift_type][shift_mode].assembler; else *assembler2_p = NULL; *cc_valid_p = shift_one[cpu][shift_type][shift_mode].cc_valid; /* Now look for cases we want to optimize. */ switch (shift_mode) { case QIshift: if (count <= 4) return SHIFT_INLINE; else { /* Shift by 5/6 are only 3 insns on the H8/S, so it's just as fast as SHIFT_ROT_AND, plus CC is valid. */ if (TARGET_H8300S && count <= 6) return SHIFT_INLINE; /* For ASHIFTRT by 7 bits, the sign bit is simply replicated through the entire value. */ if (shift_type == SHIFT_ASHIFTRT && count == 7) { *assembler_p = "shll\t%X0\n\tsubx\t%X0,%X0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } /* Other ASHIFTRTs are too much of a pain. */ if (shift_type == SHIFT_ASHIFTRT) return SHIFT_LOOP; /* Other shifts by 5, 6, or 7 bits use SHIFT_ROT_AND. */ *assembler_p = rotate_one[cpu][shift_type][shift_mode]; if (TARGET_H8300S) *assembler2_p = rotate_two[shift_type][shift_mode]; *cc_valid_p = 0; return SHIFT_ROT_AND; } case HIshift: if (count <= 4) return SHIFT_INLINE; else if (TARGET_H8300S && count <= 7) return SHIFT_INLINE; else if (count == 7) { if (shift_type == SHIFT_ASHIFT && TARGET_H8300) { *assembler_p = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.b\t%t0\n\trotr.b\t%s0\n\tand.b\t#0x80,%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } if (shift_type == SHIFT_ASHIFT && TARGET_H8300H) { *assembler_p = "shar.b\t%t0\n\tmov.b\t%s0,%t0\n\trotxr.w\t%T0\n\tand.b\t#0x80,%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } if (shift_type == SHIFT_LSHIFTRT && TARGET_H8300) { *assembler_p = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\trotl.b\t%t0\n\tand.b\t#0x01,%t0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } if (shift_type == SHIFT_LSHIFTRT && TARGET_H8300H) { *assembler_p = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.w\t%T0\n\tand.b\t#0x01,%t0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } if (shift_type == SHIFT_ASHIFTRT) { *assembler_p = "shal.b\t%s0\n\tmov.b\t%t0,%s0\n\trotxl.b\t%s0\n\tsubx\t%t0,%t0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 8) { switch (shift_type) { case SHIFT_ASHIFT: *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: *assembler_p = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: if (TARGET_H8300) *assembler_p = "mov.b\t%t0,%s0\n\tshll\t%t0\n\tsubx\t%t0,%t0\t"; else *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 9) { switch (shift_type) { case SHIFT_ASHIFT: *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: *assembler_p = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: if (TARGET_H8300) *assembler_p = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0"; else *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 10) { switch (shift_type) { case SHIFT_ASHIFT: if (TARGET_H8300S) *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\t"; else *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: if (TARGET_H8300S) *assembler_p = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0"; else *assembler_p = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: if (TARGET_H8300) *assembler_p = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0"; else if (TARGET_H8300H) *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0"; else if (TARGET_H8300S) *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 11) { switch (shift_type) { case SHIFT_ASHIFT: if (TARGET_H8300S) *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\tshal.b\t%t0"; else *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: if (TARGET_H8300S) *assembler_p = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0\n\tshlr.b\t%s0"; else *assembler_p = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: if (TARGET_H8300) *assembler_p = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0"; else if (TARGET_H8300H) *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0"; else if (TARGET_H8300S) *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 12) { switch (shift_type) { case SHIFT_ASHIFT: if (TARGET_H8300S) *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t#2,%t0\n\tshal.b\t#2,%t0"; else *assembler_p = "mov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0\n\tshal.b\t%t0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: if (TARGET_H8300S) *assembler_p = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t#2,%s0\n\tshlr.b\t#2,%s0"; else *assembler_p = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0\n\tshlr.b\t%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: if (TARGET_H8300) *assembler_p = "mov.b\t%t0,%s0\n\tbld\t#7,%s0\n\tsubx\t%t0,%t0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0"; else if (TARGET_H8300H) *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0\n\tshar.b\t%s0"; else if (TARGET_H8300S) *assembler_p = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.b\t#2,%s0\n\tshar.b\t#2,%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (!TARGET_H8300 && (count == 13 || count == 14) || count == 15) { if (count == 15 && shift_type == SHIFT_ASHIFTRT) { *assembler_p = "shll\t%t0,%t0\n\tsubx\t%t0,%t0\n\tmov.b\t%t0,%s0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } else if (shift_type != SHIFT_ASHIFTRT) { *assembler_p = rotate_one[cpu][shift_type][shift_mode]; if (TARGET_H8300S) *assembler2_p = rotate_two[shift_type][shift_mode]; else *assembler2_p = NULL; *cc_valid_p = 0; return SHIFT_ROT_AND; } } break; case SIshift: if (count <= (TARGET_H8300 ? 2 : 4)) return SHIFT_INLINE; else if (TARGET_H8300S && count <= 10) return SHIFT_INLINE; else if (count == 8 && TARGET_H8300) { switch (shift_type) { case SHIFT_ASHIFT: *assembler_p = "mov.b\t%y0,%z0\n\tmov.b\t%x0,%y0\n\tmov.b\t%w0,%x0\n\tsub.b\t%w0,%w0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: *assembler_p = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tsub.b\t%z0,%z0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: *assembler_p = "mov.b\t%x0,%w0\n\tmov.b\t%y0,%x0\n\tmov.b\t%z0,%y0\n\tshll\t%z0\n\tsubx\t%z0,%z0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 8 && !TARGET_H8300) { switch (shift_type) { case SHIFT_ASHIFT: *assembler_p = "mov.w\t%e0,%f4\n\tmov.b\t%s4,%t4\n\tmov.b\t%t0,%s4\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f4,%e0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: *assembler_p = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\textu.w\t%f4\n\tmov.w\t%f4,%e0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: *assembler_p = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\texts.w\t%f4\n\tmov.w\t%f4,%e0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 16) { switch (shift_type) { case SHIFT_ASHIFT: *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: if (TARGET_H8300) *assembler_p = "mov.w\t%e0,%f0\n\tshll\t%z0\n\tsubx\t%z0,%z0\n\tmov.b\t%z0,%y0"; else *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 17 && !TARGET_H8300) { switch (shift_type) { case SHIFT_ASHIFT: *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 18 && !TARGET_H8300) { switch (shift_type) { case SHIFT_ASHIFT: if (TARGET_H8300S) *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0"; else *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0\n\tshll.l\t%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: if (TARGET_H8300S) *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0"; else *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0\n\tshlr.l\t%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: if (TARGET_H8300S) *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0"; else *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 19 && !TARGET_H8300) { switch (shift_type) { case SHIFT_ASHIFT: if (TARGET_H8300S) *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0\n\tshll.l\t%S0"; else *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t%S0\n\tshll.l\t%S0\n\tshll.l\t%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: if (TARGET_H8300S) *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0\n\tshlr.l\t%S0"; else *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t%S0\n\tshlr.l\t%S0\n\tshlr.l\t%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: if (TARGET_H8300S) *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t%S0"; else *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0\n\tshar.l\t%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 20 && TARGET_H8300S) { switch (shift_type) { case SHIFT_ASHIFT: *assembler_p = "mov.w\t%f0,%e0\n\tsub.w\t%f0,%f0\n\tshll.l\t#2,%S0\n\tshll.l\t#2,%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_LSHIFTRT: *assembler_p = "mov.w\t%e0,%f0\n\tsub.w\t%e0,%e0\n\tshlr.l\t#2,%S0\n\tshlr.l\t#2,%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; case SHIFT_ASHIFTRT: *assembler_p = "mov.w\t%e0,%f0\n\texts.l\t%S0\n\tshar.l\t#2,%S0\n\tshar.l\t#2,%S0"; *cc_valid_p = 0; return SHIFT_SPECIAL; } } else if (count == 24 && !TARGET_H8300) { switch (shift_type) { case SHIFT_ASHIFT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -