to genbop2 op e | e1 e2 ty1 ty2 t =
    e1 = car e
    e2 = item2 e
    ty1 = typeX e1
    ty2 = typeX e2
    if and (ty1 == xLV) (isCommute op)
        genex e2
        outa op cdr e1
    else if and (ty1 == xLV) (isLogic op)
        genex e2
        outa (invLogic op) cdr e1
    else if and (ty1 == xLIT) (ty2 == xLIT)
        // still cannot do recursively
        outa icLit (evalBop op (cdr e1) (cdr e2))
    else if ty2 == xLV
        genex e1
        outa op cdr e2
    else if and (ty2 == xLIT) (op == icAdd)
        genex e1
        outa icAddi cdr e2
    else if and (ty2 == xLIT) (op == icSub)
        genex e1
        outa icSubi cdr e2
    else if isShift op
        // ty2 must be xLIT
        genex e1
        outa op cdr e2
    else
        t = newv
        genex e2
        outa icPut t
        genex e1
        outa op t
        freev t

// e = (ex0 block)
to gencase2 e | e1 n lo hi i ads v1 v2 =
    e1 = car e
    if isLocal e1
        v1 = cdr e1
    else
        genex e1			// gen ex0
        v1 = newv
        outa icPut v1
    e = cdr item2 e			// block => (ex..ex)

    // get case label range
    n = cdr car car e		// e = (num ex), n = num.ref
    lo = n
    hi = n
    e1 = e
    while e1 != NIL
        n = cdr car car e1
        if n < 0 break
        if n < lo lo = n
        if n > hi hi = n
        e1 = cdr e1

    outa icLit hi
    out3 icCase lo v1
    outa icJmp 0		// else
    ads = CP
    for i lo hi
        outa icJmp 0	// empty jmp vector
    v1 = 0
    while e != NIL
        e1 = car e		// e1 = (num ex)
        n = cdr car e1 	// n = num label
        if n > 0				// skip else (-1)
            v2 = 2*(n-lo)+ads
            patch v2 CP 		// entry in jmp vector
            genex item2 e1
            outa icJmp v1		// jmp to eloc, backchain
            v1 = lastCP
        e = cdr e

    patch ads-2 CP		// here is exelse
    for i lo hi
        v2 = 2*(i-lo)+ads
        if CS[v2+1] == 0
            patch v2 CP	// patch empty entry to here
    if n == #f			// gen else case -1
        genex item2 e1
    // here is eloc
    // update backchain jmp to eloc
    while v1 != 0
        v2 = CS[v1+1]
        patch v1 CP
        v1 = v2

