Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!crdgw1!uakari.primate.wisc.edu!sdd.hp.com!cs.utexas.edu!chinacat!uudell!bigtex!james From: james@bigtex.cactus.org (James Van Artsdalen) Newsgroups: comp.unix.sysv386 Subject: Re: X386 problem: Xaw i/make cannot find _divsi3. What/where is it? Message-ID: <60816@bigtex.cactus.org> Date: 16 May 91 04:23:39 GMT References: <1991May15.002226.12738@lynx.CS.ORST.EDU> <1991May15.153752.6208@thyme.jpl.nasa.gov> Reply-To: james@bigtex.cactus.org (James Van Artsdalen) Distribution: na Organization: Institute of Applied Cosmology, Austin TX Lines: 150 In <1991May15.153752.6208@thyme.jpl.nasa.gov>, kaleb@thyme.jpl.nasa.gov (Kaleb Keithley) wrote: > In article holtt@jacobs.CS.ORST.EDU (Tim Holt) writes: | I get 3 undefined symbols: _divsi3, _fxdfsi (both in libXaw.a), | and _udivsi3 (in libXt.a). > These are long long arithmetic functions from gnulib. Actually, _divsi3 is signed 32 bit division, _udivsi3 is unsigned 32 bit division, and _fixdfsi is double->int conversion. gcc version 1 has little if any long long support in i386.md. gcc version 2 will support it better. I'm not sure why the divide patterns are being used from gnulib - gcc has patterns for divmodsi4 & udivmodsi4. If someone can induce gcc 1.39 to call _divsi3 or _udivsi3, I'd like to know how as I think it is a bug. As for converting double to int, that change probably won't be made to gcc version 1 unless there is a strong need. But, here are the changes to do it if you like. Don't report bugs to gnu.gcc.bug: mail them to me. First, add these three patterns to i386.md: (define_expand "fix_truncdfdi2" [(parallel [(set (match_operand:DI 0 "general_operand" "") (fix:DI (fix:DF (match_operand:DF 1 "general_operand" "")))) (clobber (match_dup 2))])] "TARGET_80387" "operands[2] = gen_reg_rtx (HImode);") (define_expand "fixuns_truncdfdi2" [(parallel [(set (match_operand:DI 0 "general_operand" "") (fix:DI (fix:DF (match_operand:DF 1 "general_operand" "")))) (clobber (match_dup 2))])] "TARGET_80387" "operands[2] = gen_reg_rtx (HImode);") (define_insn "fix_truncdfdi2_1" [(set (match_operand:DI 0 "general_operand" "=m,?*r") (fix:DI (fix:DF (match_operand:DF 1 "general_operand" "f,f")))) (clobber (match_operand:HI 2 "register_operand" "=r,r"))] "TARGET_80387" "*output_fix_trunc (operands); RET;") ===== Then, in out-i386.c, in print_operand(), add the two lines marked below: >> case 'D': >> PUT_OP_SIZE (code, 'l', file); case 'L': PUT_OP_SIZE (code, 'l', file); return; ===== Also in out-i386.c, replace fp_pop_int() with this and remove the #if 0 / #endif that surrounds the function: /* Pop the fp stack, convert value to integer and store in TARGET. TARGET may be memory or register, and may have QI, HI or SImode. */ void fp_pop_int (target) rtx target; { if (REG_P (target)) { rtx xops[3]; xops[0] = stack_pointer_rtx; xops[1] = gen_rtx (CONST_INT, VOIDmode, GET_MODE_SIZE (GET_MODE (target))); output_asm_insn (AS2 (sub%L0,%1,%0), xops); /* fp_pop_level--; */ xops[0] = AT_SP (Pmode); if (GET_MODE (target) == SImode) { output_asm_insn (AS1 (fistp%L0,%0), xops); output_asm_insn (AS1 (pop%L0,%0), &target); } else if (GET_MODE (target) == DImode) { xops[1] = gen_rtx (REG, SImode, REGNO (target)); xops[2] = gen_rtx (REG, SImode, REGNO (target) + 1); output_asm_insn (AS1 (fistp%D0,%0), xops); output_asm_insn (AS1 (pop%L1,%1), xops); output_asm_insn (AS1 (pop%L2,%2), xops); } else abort(); } else if (GET_CODE (target) == MEM) { if (GET_MODE (target) == DImode) output_asm_insn (AS1 (fistp%D0,%0), &target); else if (GET_MODE (target) == SImode) output_asm_insn (AS1 (fistp%L0,%0), &target); else abort(); } else abort (); } ===== Lastly, add this to the end of out-i386.c: void output_fix_trunc (operands) rtx *operands; { rtx xops[6]; if (!FP_REG_P (operands[1])) abort (); xops[0] = stack_pointer_rtx; xops[1] = AT_SP (HImode); xops[2] = adj_offsettable_operand (xops[1], 2); xops[3] = gen_rtx (CONST_INT, VOIDmode, 4); xops[4] = gen_rtx (CONST_INT, VOIDmode, 0xc00); xops[5] = operands[2]; output_asm_insn (AS2 (sub%L0,%3,%0), xops); output_asm_insn ("fnstcw %1", xops); output_asm_insn (AS2 (mov%W5,%1,%5), xops); output_asm_insn (AS2 (or%W5,%4,%5), xops); output_asm_insn (AS2 (mov%W5,%5,%2), xops); output_asm_insn ("fldcw %2", xops); fp_pop_int (operands[0]); output_asm_insn ("fldcw %1", xops); output_asm_insn (AS2 (add%L0,%3,%0), xops); } -- James R. Van Artsdalen james@bigtex.cactus.org "Live Free or Die" Dell Computer Co 9505 Arboretum Blvd Austin TX 78759 512-338-8789