static void
nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx)
{
	int len = nv44_graph_class(ctx->dev) ? 0x0084 : 0x0684;

	cp_out (ctx, 0x300000);
	cp_lsr (ctx, len - 4);
	cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_swap_state3d_3_is_save);
	cp_lsr (ctx, len);
	cp_name(ctx, cp_swap_state3d_3_is_save);
	cp_out (ctx, 0x800001);

	ctx->ctxvals_pos += len;
}
static void
nv40_grctx_generate(struct nouveau_grctx *ctx)
{
	/* decide whether we're loading/unloading the context */
	cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save);
	cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save);

	cp_name(ctx, cp_check_load);
	cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load);
	cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load);
	cp_bra (ctx, ALWAYS, TRUE, cp_exit);

	/* setup for context load */
	cp_name(ctx, cp_setup_auto_load);
	cp_wait(ctx, STATUS, IDLE);
	cp_out (ctx, CP_NEXT_TO_SWAP);
	cp_name(ctx, cp_setup_load);
	cp_wait(ctx, STATUS, IDLE);
	cp_set (ctx, SWAP_DIRECTION, LOAD);
	cp_out (ctx, 0x00910880); /* ?? */
	cp_out (ctx, 0x00901ffe); /* ?? */
	cp_out (ctx, 0x01940000); /* ?? */
	cp_lsr (ctx, 0x20);
	cp_out (ctx, 0x0060000b); /* ?? */
	cp_wait(ctx, UNK57, CLEAR);
	cp_out (ctx, 0x0060000c); /* ?? */
	cp_bra (ctx, ALWAYS, TRUE, cp_swap_state);

	/* setup for context save */
	cp_name(ctx, cp_setup_save);
	cp_set (ctx, SWAP_DIRECTION, SAVE);

	/* general PGRAPH state */
	cp_name(ctx, cp_swap_state);
	cp_pos (ctx, 0x00020/4);
	nv40_graph_construct_general(ctx);
	cp_wait(ctx, STATUS, IDLE);

	/* 3D state, block 1 */
	cp_bra (ctx, UNK54, CLEAR, cp_prepare_exit);
	nv40_graph_construct_state3d(ctx);
	cp_wait(ctx, STATUS, IDLE);

	/* 3D state, block 2 */
	nv40_graph_construct_state3d_2(ctx);

	/* Some other block of "random" state */
	nv40_graph_construct_state3d_3(ctx);

	/* Per-vertex shader state */
	cp_pos (ctx, ctx->ctxvals_pos);
	nv40_graph_construct_shader(ctx);

	/* pre-exit state updates */
	cp_name(ctx, cp_prepare_exit);
	cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load);
	cp_bra (ctx, USER_SAVE, PENDING, cp_exit);
	cp_out (ctx, CP_NEXT_TO_CURRENT);

	cp_name(ctx, cp_exit);
	cp_set (ctx, USER_SAVE, NOT_PENDING);
	cp_set (ctx, USER_LOAD, NOT_PENDING);
	cp_out (ctx, CP_END);
}
void
nv40_grctx_init(struct nouveau_grctx *ctx)
{

    cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save);
    cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save);

    cp_name(ctx, cp_check_load);
    cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load);
    cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load);
    cp_bra (ctx, ALWAYS, TRUE, cp_exit);


    cp_name(ctx, cp_setup_auto_load);
    cp_wait(ctx, STATUS, IDLE);
    cp_out (ctx, CP_NEXT_TO_SWAP);
    cp_name(ctx, cp_setup_load);
    cp_wait(ctx, STATUS, IDLE);
    cp_set (ctx, SWAP_DIRECTION, LOAD);
    cp_out (ctx, 0x00910880);
    cp_out (ctx, 0x00901ffe);
    cp_out (ctx, 0x01940000);
    cp_lsr (ctx, 0x20);
    cp_out (ctx, 0x0060000b);
    cp_wait(ctx, UNK57, CLEAR);
    cp_out (ctx, 0x0060000c);
    cp_bra (ctx, ALWAYS, TRUE, cp_swap_state);


    cp_name(ctx, cp_setup_save);
    cp_set (ctx, SWAP_DIRECTION, SAVE);


    cp_name(ctx, cp_swap_state);
    cp_pos (ctx, 0x00020/4);
    nv40_graph_construct_general(ctx);
    cp_wait(ctx, STATUS, IDLE);


    cp_bra (ctx, UNK54, CLEAR, cp_prepare_exit);
    nv40_graph_construct_state3d(ctx);
    cp_wait(ctx, STATUS, IDLE);


    nv40_graph_construct_state3d_2(ctx);


    nv40_graph_construct_state3d_3(ctx);


    cp_pos (ctx, ctx->ctxvals_pos);
    nv40_graph_construct_shader(ctx);


    cp_name(ctx, cp_prepare_exit);
    cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load);
    cp_bra (ctx, USER_SAVE, PENDING, cp_exit);
    cp_out (ctx, CP_NEXT_TO_CURRENT);

    cp_name(ctx, cp_exit);
    cp_set (ctx, USER_SAVE, NOT_PENDING);
    cp_set (ctx, USER_LOAD, NOT_PENDING);
    cp_out (ctx, CP_END);
}