📄 tahoe.md
字号:
(compare (zero_extend:SI (match_operand:QI 0 "memory_operand" "m")) (match_operand:SI 1 "immediate_operand" "i")))] "tahoe_cmp_check(insn, operands[1], 255)" "*{ if (INTVAL (operands[1]) > 127) operands[1] = GEN_INT (INTVAL (operands[1]) + 0xffffff00); return \"cmpb %0,%1\";}")(define_insn "cmpsi" [(set (cc0) (compare (match_operand:SI 0 "nonimmediate_operand" "g") (match_operand:SI 1 "general_operand" "g")))] "" "cmpl %0,%1"); cmpsf similar to vax, but first operand is expected to be in the; fpp accumulator.(define_insn "cmpsf" [(set (cc0) (compare (match_operand:SF 0 "general_operand" "a,g") (match_operand:SF 1 "general_operand" "g,g")))] "" "*{ switch (which_alternative) { case 0: return \"cmpf %1\"; case 1: return \"cmpf2 %0,%1\"; }}"); cmpdf similar to vax, but first operand is expected to be in the; fpp accumulator. Immediate doubles not allowed.(define_insn "cmpdf" [(set (cc0) (compare (match_operand:DF 0 "general_operand" "a,rm") (match_operand:DF 1 "general_operand" "rm,rm")))] "" "*{ switch (which_alternative) { case 0: return \"cmpd %1\"; case 1: return \"cmpd2 %0,%1\"; }}");; We don't want to allow a constant operand for test insns because;; (set (cc0) (const_int foo)) has no mode information. Such insns will;; be folded while optimizing anyway.(define_insn "tstsi" [(set (cc0) (match_operand:SI 0 "nonimmediate_operand" "g"))] "" "tstl %0"); small tests from memory are normal, but testing from registers doesn't; expand the data properly. So test in this case does a convert and tests; the new register data from the stack.; First some special cases that do work(define_insn "" [(set (cc0) (sign_extend:SI (match_operand:HI 0 "memory_operand" "m")))] "" "tstw %0")(define_insn "" [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "m")))] "tahoe_cmp_check (insn, operands[0], 0)" "tstw %0")(define_insn "tsthi" [(set (cc0) (match_operand:HI 0 "extensible_operand" "m,!r"))] "GET_MODE (operands[0]) != VOIDmode" "*{ rtx xoperands[2]; extern rtx tahoe_reg_conversion_loc; switch (which_alternative) { case 0: return \"tstw %0\"; case 1: xoperands[0] = operands[0]; xoperands[1] = tahoe_reg_conversion_loc; output_asm_insn (\"movl %0,%1\", xoperands); xoperands[1] = plus_constant (XEXP (tahoe_reg_conversion_loc, 0), 2); output_asm_insn (\"tstw %a1\", xoperands); return \"\"; }}")(define_insn "" [(set (cc0) (sign_extend:SI (match_operand:QI 0 "memory_operand" "m")))] "" "tstb %0")(define_insn "" [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "m")))] "tahoe_cmp_check (insn, operands[0], 0)" "tstb %0")(define_insn "tstqi" [(set (cc0) (match_operand:QI 0 "extensible_operand" "m,!r"))] "GET_MODE (operands[0]) != VOIDmode" "*{ rtx xoperands[2]; extern rtx tahoe_reg_conversion_loc; switch (which_alternative) { case 0: return \"tstb %0\"; case 1: xoperands[0] = operands[0]; xoperands[1] = tahoe_reg_conversion_loc; output_asm_insn (\"movl %0,%1\", xoperands); xoperands[1] = plus_constant (XEXP (tahoe_reg_conversion_loc, 0), 3); output_asm_insn (\"tstb %a1\", xoperands); return \"\"; }}"); tstsf compares a given value to a value already in the fpp accumulator.; No flags are set by this so ignore them.(define_insn "tstsf" [(set (cc0) (match_operand:SF 0 "register_operand" "a"))] "" "tstf"); tstdf compares a given value to a value already in the fpp accumulator.; immediate doubles not allowed. Flags are ignored after this.(define_insn "tstdf" [(set (cc0) (match_operand:DF 0 "register_operand" "a"))] "" "tstd"); movstrhi tahoe instruction does not load registers by itself like; the vax counterpart does. registers 0-2 must be primed by hand.; we have loaded the registers in the order: dst, src, count.(define_insn "movstrhi" [(set (match_operand:BLK 0 "general_operand" "p") (match_operand:BLK 1 "general_operand" "p")) (use (match_operand:HI 2 "general_operand" "g")) (clobber (reg:SI 0)) (clobber (reg:SI 1)) (clobber (reg:SI 2))] "" "movab %0,r1\;movab %1,r0\;movl %2,r2\;movblk"); floatsisf2 on tahoe converts the long from reg/mem into the fpp; accumulator. There are no hi and qi counterparts. Flags are not; set correctly here.(define_insn "floatsisf2" [(set (match_operand:SF 0 "register_operand" "=a") (float:SF (match_operand:SI 1 "general_operand" "g")))] "" "*{ CC_STATUS_INIT; return \"cvlf %1\";}"); floatsidf2 on tahoe converts the long from reg/mem into the fpp; accumulator. There are no hi and qi counterparts. Flags are not; set correctly here.(define_insn "floatsidf2" [(set (match_operand:DF 0 "register_operand" "=a") (float:DF (match_operand:SI 1 "general_operand" "g")))] "" "*{ CC_STATUS_INIT; return \"cvld %1\";}"); fix_truncsfsi2 to convert a float to long, tahoe must have the float; in the fpp accumulator. Flags are not set here.(define_insn "fix_truncsfsi2" [(set (match_operand:SI 0 "general_operand" "=g") (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "a"))))] "" "*{ CC_STATUS_INIT; return \"cvfl %0\";}"); fix_truncsfsi2 to convert a double to long, tahoe must have the double; in the fpp accumulator. Flags are not set here.(define_insn "fix_truncdfsi2" [(set (match_operand:SI 0 "general_operand" "=g") (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a"))))] "" "*{ CC_STATUS_INIT; return \"cvdl %0\";}")(define_insn "truncsihi2" [(set (match_operand:HI 0 "general_operand" "=g") (truncate:HI (match_operand:SI 1 "general_operand" "g")))] "" "cvtlw %1,%0")(define_insn "truncsiqi2" [(set (match_operand:QI 0 "general_operand" "=g") (truncate:QI (match_operand:SI 1 "general_operand" "g")))] "" "cvtlb %1,%0")(define_insn "trunchiqi2" [(set (match_operand:QI 0 "general_operand" "=g") (truncate:QI (match_operand:HI 1 "general_operand" "g")))] "" "cvtwb %1,%0"); The fpp related instructions don't set flags, so ignore them; after this instruction.(define_insn "truncdfsf2" [(set (match_operand:SF 0 "register_operand" "=a") (float_truncate:SF (match_operand:DF 1 "register_operand" "0")))] "" "*{ CC_STATUS_INIT; return \"cvdf\";}"); This monster is to cover for the Tahoe's nasty habit of not extending; a number if the source is in a register. (It just moves it!) Case 0 is; a normal extend from memory. Case 1 does the extension from the top of; the stack. Extension from the stack doesn't set the flags right since; the moval changes them.(define_insn "extendhisi2" [(set (match_operand:SI 0 "general_operand" "=g,?=g") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))] "" "*{ switch (which_alternative) { case 0: return \"cvtwl %1,%0\"; case 1: if (push_operand (operands[0], SImode)) return \"pushl %1\;cvtwl 2(sp),(sp)\"; else { CC_STATUS_INIT; return \"pushl %1\;cvtwl 2(sp),%0\;moval 4(sp),sp\"; } }}"); This monster is to cover for the Tahoe's nasty habit of not extending; a number if the source is in a register. (It just moves it!) Case 0 is; a normal extend from memory. Case 1 does the extension from the top of; the stack. Extension from the stack doesn't set the flags right since; the moval changes them.(define_insn "extendqisi2" [(set (match_operand:SI 0 "general_operand" "=g,?=g") (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] "" "*{ switch (which_alternative) { case 0: return \"cvtbl %1,%0\"; case 1: if (push_operand (operands[0], SImode)) return \"pushl %1\;cvtbl 3(sp),(sp)\"; else { CC_STATUS_INIT; return \"pushl %1\;cvtbl 3(sp),%0\;moval 4(sp),sp\"; } }}"); This monster is to cover for the Tahoe's nasty habit of not extending; a number if the source is in a register. (It just moves it!) Case 0 is; a normal extend from memory. Case 1 does the extension from the top of; the stack. Extension from the stack doesn't set the flags right since; the moval changes them.(define_insn "extendqihi2" [(set (match_operand:HI 0 "general_operand" "=g,?=g") (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] "" "*{ switch (which_alternative) { case 0: return \"cvtbw %1,%0\"; case 1: if (push_operand (operands[0], SImode)) return \"pushl %1\;cvtbw 3(sp),(sp)\"; else { CC_STATUS_INIT; return \"pushl %1\;cvtbw 3(sp),%0\;moval 4(sp),sp\"; } }}"); extendsfdf2 tahoe uses the fpp accumulator to do the extension.; It takes a float and loads it up directly as a double.(define_insn "extendsfdf2" [(set (match_operand:DF 0 "register_operand" "=a") (float_extend:DF (match_operand:SF 1 "general_operand" "g")))] "" "*{ CC_STATUS_INIT; return \"ldfd %1\";}"); movz works fine from memory but not from register for the same reasons; the cvt instructions don't work right. So we use the normal instruction; from memory and we use an and to simulate it from register. This is faster; than pulling it off the stack.(define_insn "zero_extendhisi2" [(set (match_operand:SI 0 "general_operand" "=g,?=g") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))] "" "*{ switch (which_alternative) { case 0: return \"movzwl %1,%0\"; case 1: return \"andl3 $0xffff,%1,%0\"; }}"); movz works fine from memory but not from register for the same reasons; the cvt instructions don't work right. So we use the normal instruction; from memory and we use an and to simulate it from register. This is faster; than pulling it off the stack.(define_insn "zero_extendqihi2" [(set (match_operand:HI 0 "general_operand" "=g,?=g") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] "" "*{ switch (which_alternative) { case 0: return \"movzbw %1,%0\"; case 1: return \"andw3 $0xff,%1,%0\"; }}"); movz works fine from memory but not from register for the same reasons; the cvt instructions don't work right. So we use the normal instruction; from memory and we use an and to simulate it from register. This is faster; than pulling it off the stack.(define_insn "zero_extendqisi2" [(set (match_operand:SI 0 "general_operand" "=g,?=g") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))] "" "*{ switch (which_alternative) { case 0: return \"movzbl %1,%0\"; case 1: return \"andl3 $0xff,%1,%0\"; }}")(define_insn "beq" [(set (pc) (if_then_else (eq (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jeql %l0")(define_insn "bne" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jneq %l0")(define_insn "bgt" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jgtr %l0")(define_insn "bgtu" [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jgtru %l0")(define_insn "blt" [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jlss %l0")(define_insn "bltu" [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jlssu %l0")(define_insn "bge" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jgeq %l0")(define_insn "bgeu" [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jgequ %l0")(define_insn "ble" [(set (pc) (if_then_else (le (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jleq %l0")(define_insn "bleu" [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jlequ %l0"); gcc does not account for register mask/argc longword. Thus the number; for the call = number bytes for args + 4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -