Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!rutgers!seismo!mimsy!chris From: chris@mimsy.UUCP Newsgroups: comp.lang.c Subject: Re: Long Branches Message-ID: <5107@mimsy.UUCP> Date: Mon, 19-Jan-87 00:34:15 EST Article-I.D.: mimsy.5107 Posted: Mon Jan 19 00:34:15 1987 Date-Received: Mon, 19-Jan-87 06:29:48 EST References: <3950006@nucsrl.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 81 In article <3950006@nucsrl.UUCP> ram@nucsrl.UUCP (Raman Renu) writes: >... using the C compiler and VAX assembler in our local 4.3BSD(VAX) site. >I have a program which has a huge(>900lines) case statement. >The assembler chokes on (>32K long) long branches. This may seem a nit, but no, the assembler chokes on >32K *word* branches. This is an important distinction. The pseudo-ops `jbr' expand into one of `brb' or `brw', but not `jmp'. The Vax does not have a long branch instruction, just a long jump instruction (the difference is that one takes an offset, the other an address). >Apparently there is a flag "-J" for such purposes (in the assembler) >which does not seem to work. Indeed, it does work. Look more closely at the error messages! >The ouput of the C compiler was (To be technical, these errors are from the assembler.) >Assembler: >"/tmp/ctm088343", line 2565: brw: Branch too far(50148b): try -J flag >"/tmp/ctm088343", line 2823: brw: Branch too far(48806b): try -J flag >"/tmp/ctm088343", line 2922: brw: Branch too far(48313b): try -J flag >"/tmp/ctm088343", line 12658: Case will branch too far >"/tmp/ctm088343", line 12659: Case will branch too far >"/tmp/ctm088343", line 12664: Case will branch too far Three are `branch too far, try -J'. Three are something else. >and the ouput of a seperate assembly [with -J] had the same error >message(predictably). No, not the same! >Assembler: >"prolog.s", line 13337: Case will branch too far >"prolog.s", line 13338: Case will branch too far >"prolog.s", line 13339: Case will branch too far >"prolog.s", line 13340: Case will branch too far All three `branch too far, try -J's are gone. There is one new `case will branch too far' message (because the code got bigger). The problem is that the Vax `case' instruction has only a word offset for its branches. If you look at the result of compiling a switch statement, you can see this yourself: f() { extern int sw; switch (sw) { #define CASE(n) case n: f/**/n(); break /* kludge; no ## yet */ CASE(0); CASE(1); CASE(2); CASE(3); CASE(4); CASE(5); CASE(6); CASE(7); } } The switch compiles as: casel r0,$0,$7 # note that this is a `long' case L35: .word L19-L35 # For case 0, branch to L19, .word L21-L35 # and so on. .word L23-L35 # Note that these are only word .word L25-L35 # offsets; no long offsets are .word L27-L35 # available. .word L29-L35 .word L31-L35 .word L33-L35 There is nothing the assembler can do at this point. You have several alternatives: alter the compiler to produce a series of if/else tests (preferably via a -J flag); edit the assembly to be a series of if/else tests; or restructure your C code, splitting up the switch statement or making the cases shorter. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) UUCP: seismo!mimsy!chris ARPA/CSNet: chris@mimsy.umd.edu