static obj_t string_copy_fn(obj_t args, Reporter rep) { string str; if (!args_match(rep, args, 1, is_string)) return unspecific; str = fetch_string(list_ref(args, 0)); return make_string(string_clone(str)); }
static obj_t string_length_fn(obj_t args, Reporter rep) { obj_t obj; if (!args_match(rep, args, 1, is_string)) return unspecific; obj = list_ref(args, 0); return make_num(fetch_string(obj)->len); }
static obj_t string_predicate_fn(obj_t args, Reporter rep) { obj_t obj; if (!args_match(rep, args, 1, is_obj)) return unspecific; obj = list_ref(args, 0); return make_bool(is_string(obj)); }
static obj_t string_fill_fn(obj_t args, Reporter rep) { string str; char ch; if (!args_match(rep, args, 2, is_string, is_char)) return unspecific; str = fetch_string(list_ref(args, 0)); ch = fetch_char(list_ref(args, 1)); memset(str->data, ch, str->len); return unspecific; }
static obj_t string_ci_ge_fn(obj_t args, Reporter rep) { obj_t s1, s2; int rv; if (!args_match(rep, args, 2, is_string, is_string)) return unspecific; s1 = list_ref(args, 0); s2 = list_ref(args, 1); rv = string_ci_cmp(fetch_string(s1), fetch_string(s2)); return make_bool(rv >= 0); }
void process_args( int *argc, char *argv[], param *p ) { int i, j, subtract; i = 1; while ( i<*argc ) { subtract = 0; if ( args_match( argv[i], "-h", "--help" ) ) { help( p->progname ); exit( EXIT_SUCCESS ); } else if ( args_match( argv[i], "-v", "--version" ) ) { args_tellversion( p->progname ); exit( EXIT_SUCCESS ); } else if ( args_match( argv[i], "-s", "--single-refperfile")) { p->singlerefperfile = 1; subtract = 1; } else if ( args_match( argv[i], "-nb", "--no-bom" ) ) { p->utf8bom = 0; subtract = 1; } else if ( args_match( argv[i], "--verbose", "" ) ) { p->verbose = 1; subtract = 1; } else if ( args_match( argv[i], "--debug", "" ) ) { p->verbose = 3; subtract = 1; } if ( subtract ) { for ( j=i+subtract; j<*argc; ++j ) argv[j-subtract] = argv[j]; *argc -= subtract; } else i++; } }
bool variable_intersection::args_self_match(const app * f) { if(!args_match(f,f)) { return false; } unsigned n = m_const_indexes.size(); for(unsigned i=0; i<n; i++) { unsigned f_index = m_const_indexes[i]; if(!values_match(f->get_arg(f_index), m_consts[i].get())) { return false; } } return true; }
static obj_t string2list_fn(obj_t args, Reporter rep) { obj_t string, list = null_obj; char *cs; size_t n, i; if (!args_match(rep, args, 1, is_string)) return unspecific; string = list_ref(args, 0); cs = fetch_string(string)->data; n = fetch_string(string)->len; for (i = 0; i < n; i++) list = cons(make_char(cs[n-i-1]), list); return list; }
static obj_t substring_fn(obj_t args, Reporter rep) { string str; long start, end; if (!args_match(rep, args, 3, is_string, is_num, is_num)) return unspecific; str = fetch_string(list_ref(args, 0)); start = fetch_num(list_ref(args, 1)); end = fetch_num(list_ref(args, 2)); if (!(0 <= start && start <= end && end <= (long)str->len)) { reportf(rep, "substring: invalid range [%d, %d)", start, end); return unspecific; } return make_string(string_from(str->data + start, end - start)); }
static obj_t string_ref_fn(obj_t args, Reporter rep) { obj_t obj, idx; long k; if (!args_match(rep, args, 2, is_string, is_num)) return unspecific; obj = list_ref(args, 0); idx = list_ref(args, 1); k = fetch_num(idx); if (k < 0 || (size_t)k >= fetch_string(obj)->len) { reportf(rep, "string-ref: index %ld is out of range", k); return unspecific; } return make_char(fetch_string(obj)->data[k]); }
static obj_t string_set_fn(obj_t args, Reporter rep) { obj_t obj, idx, chr; long k; if (!args_match(rep, args, 3, is_string, is_num, is_char)) return unspecific; obj = list_ref(args, 0); idx = list_ref(args, 1); chr = list_ref(args, 2); k = fetch_num(idx); if (k < 0 || (size_t)k >= fetch_string(obj)->len) { reportf(rep, "string-set!: index %ld is out of range", k); return unspecific; } fetch_string(obj)->data[k] = fetch_char(chr); return unspecific; }
void process_args( int *argc, char *argv[], param *p ) { int i, j, subtract; i = 1; while ( i < *argc ) { subtract = 0; if ( args_match( argv[i], "-h", "--help" ) ) { help( p->progname ); exit( EXIT_SUCCESS ); } else if ( args_match( argv[i], "-v", "--version" ) ) { args_tellversion( p->progname ); exit( EXIT_SUCCESS ); } else if ( args_match( argv[i], "-s", "--single-refperfile")){ p->singlerefperfile = 1; subtract = 1; } else if ( args_match( argv[i], "-nb", "--no-bom" ) ) { p->utf8bom = 0; subtract = 1; } else if ( args_match( argv[i], "--verbose", "" ) ) { p->verbose = 1; subtract = 1; } else if ( args_match( argv[i], "--debug", "" ) ) { p->verbose = 3; subtract = 1; } if ( subtract ) { for ( j=i+subtract; j<*argc; ++j ) argv[j-subtract] = argv[j]; *argc -= subtract; } else { if ( argv[i][0]=='-' ) fprintf( stderr, "Warning: Did not recognize potential command-line argument %s\n", argv[i] ); i++; } } }
void tomods_processargs( int *argc, char *argv[], param *p, char *help1, char *help2 ) { int i, j, subtract; process_charsets( argc, argv, p, 1, 0 ); i = 0; while ( i<*argc ) { subtract = 0; if ( args_match( argv[i], "-h", "--help" ) ) { subtract = 1; args_tomods_help( p->progname, help1, help2 ); exit( EXIT_SUCCESS ); } else if ( args_match( argv[i], "-v", "--version" ) ) { subtract = 1; args_tellversion( p->progname ); exit( EXIT_SUCCESS ); } else if ( args_match( argv[i], "-a", "--add-refcount" ) ) { p->addcount = 1; subtract = 1; } else if ( args_match(argv[i], NULL, "--verbose" ) ) { /* --debug + --verbose = --debug */ if ( p->verbose<1 ) p->verbose = 1; p->format_opts |= BIBL_FORMAT_VERBOSE; subtract = 1; } else if ( args_match(argv[i], NULL, "--debug" ) ) { p->verbose = 3; p->format_opts |= BIBL_FORMAT_VERBOSE; subtract = 1; } else if ( args_match( argv[i], "-d", "--drop-key" ) ) { p->format_opts |= MODSOUT_DROPKEY; subtract = 1; } else if ( args_match( argv[i], "-s", "--single-refperfile" )){ p->singlerefperfile = 1; subtract = 1; } else if ( args_match( argv[i], "-u", "--unicode-characters")){ p->utf8out = 1; p->utf8bom = 1; p->charsetout = BIBL_CHARSET_UNICODE; p->charsetout_src = BIBL_SRC_USER; subtract = 1; } else if ( args_match( argv[i], "-un", "--unicode-no-bom")){ p->utf8out = 1; p->utf8bom = 0; p->charsetout = BIBL_CHARSET_UNICODE; p->charsetout_src = BIBL_SRC_USER; subtract = 1; } else if ( args_match( argv[i], "-nl", "--no-latex" ) ) { p->latexin = 0; subtract = 1; } else if ( args_match( argv[i], "-x", "--xml-entities" ) ) { p->utf8out = 0; p->utf8bom = 0; p->xmlout = 1; subtract = 1; } else if ( args_match( argv[i], "-c", "--corporation-file")){ args_namelist( *argc, argv, i, p->progname, "-c", "--corporation-file" ); bibl_readcorps( p, argv[i+1] ); subtract = 2; } else if ( args_match( argv[i], "-as", "--asis")) { args_namelist( *argc, argv, i, p->progname, "-as", "--asis" ); bibl_readasis( p, argv[i+1] ); subtract = 2; } if ( subtract ) { for ( j=i+subtract; j<*argc; j++ ) { argv[j-subtract] = argv[j]; } *argc -= subtract; } else i++; } }
static struct expty transExp(Tr_level level, S_table v, S_table t, A_exp e){ A_oper oper; struct expty left, right, final, final2, final3, final4, final5, lo, hi; A_expList list; A_decList decs; E_enventry callinfo; Ty_ty recty, arrayty; switch (e->kind) { case A_varExp: return transVar(level, v, t, e->u.var); case A_nilExp: return expTy(NULL, Ty_Nil()); case A_callExp: callinfo = S_look(v, e->u.call.func); /*get params and return from tenv*/ if (callinfo && callinfo->kind == E_funEntry){ if (args_match(level, v, t, e->u.call.args, callinfo->u.fun.formals, e)) {/*check params is matched*/ if (callinfo->u.fun.result) { return expTy(NULL, actual_ty(callinfo->u.fun.result)); } else { return expTy(NULL, Ty_Void()); } } } else { EM_error(e->pos, "undefined function %s\n", S_name(e->u.call.func)); } return expTy(NULL, Ty_Void()); case A_recordExp: recty = actual_ty(S_look(t, e->u.record.typ)); if (!recty) { /*cant find record-type in table tenv*/ EM_error(e->pos, "undefined type %s (debug recordExp)", S_name(e->u.record.typ)); } else { if (recty->kind != Ty_record){ EM_error(e->pos, "%s is not a record type", S_name(e->u.record.typ)); return expTy(NULL, Ty_Record(NULL)); } if (efields_match(level, v, t, recty, e)) {/*check record field is matched*/ return expTy(NULL, recty); } } return expTy(NULL, Ty_Record(NULL)); case A_arrayExp: arrayty = actual_ty(S_look(t, e->u.array.typ)); if (!arrayty) { EM_error(e->pos, "undeined array type %s", S_name(e->u.array.typ)); return expTy(NULL, Ty_Array(NULL)); } if (arrayty->kind != Ty_array) { EM_error(e->pos, "%s is not a array type", S_name(e->u.array.typ)); return expTy(NULL, Ty_Array(NULL)); } final2 = transExp(level, v, t, e->u.array.size); final3 = transExp(level, v, t, e->u.array.init); if (final2.ty->kind != Ty_int) { EM_error(e->pos, "array size should be int %s", S_name(e->u.array.typ)); } else if (!ty_match(final3.ty, arrayty->u.array)){ EM_error(e->pos, "unmatched array type in %s", S_name(e->u.array.typ)); } else { return expTy(NULL, arrayty); } return expTy(NULL, Ty_Array(NULL)); case A_seqExp: list = e->u.seq; if (!list) { return expTy(NULL, Ty_Void()); } while (list->tail) { transExp(level, v, t, list->head); list = list->tail; } return transExp(level, v, t, list->head); case A_whileExp: final = transExp(level, v, t, e->u.whilee.test); if (final.ty->kind != Ty_int) { EM_error(e->pos, "int required"); } transExp(level, v, t, e->u.whilee.body); return expTy(NULL, Ty_Void()); case A_assignExp: final4 = transVar(level, v, t, e->u.assign.var); final5 = transExp(level, v, t, e->u.assign.exp); if (!ty_match(final4.ty, final5.ty)) { EM_error(e->pos, "unmatched assign exp"); } return expTy(NULL, Ty_Void()); case A_breakExp: return expTy(NULL, Ty_Void()); case A_forExp: { struct expty lo = transExp(level, v, t, e->u.forr.lo); struct expty hi = transExp(level, v, t, e->u.forr.hi); struct expty body; if (lo.ty != Ty_Int() || hi.ty != Ty_Int()) { EM_error(e->pos, "low or high range type is not integer"); } S_beginScope(v); transDec(level, v, t, A_VarDec(e->pos, e->u.forr.var, S_Symbol("int"), e->u.forr.lo)); body = transExp(level, v, t, e->u.forr.body); S_endScope(v); return expTy(NULL, Ty_Void()); } case A_letExp: S_beginScope(v); S_beginScope(t); for (decs = e->u.let.decs; decs; decs = decs->tail) { transDec(level, v, t, decs->head); } final = transExp(level, v, t, e->u.let.body); S_endScope(v); S_endScope(t); return final; case A_opExp: oper = e->u.op.oper; left = transExp(level, v, t, e->u.op.left); right = transExp(level, v, t, e->u.op.right); if (0 <= oper && oper < 4) {/* check +,-,*,/ */ if (left.ty->kind != Ty_int && left.ty->kind != Ty_double){ EM_error(e->u.op.left->pos, "int or double required(op)"); } if (right.ty->kind != Ty_int && right.ty->kind != Ty_double) { EM_error(e->u.op.right->pos, "int or double required(op)"); } if (left.ty->kind == Ty_int && right.ty->kind == Ty_int && oper != 3) { return expTy(NULL, Ty_Int()); } else { /*TODO divide when return double when return int*/ /* return expTy(NULL, Ty_Int()); */ return expTy(NULL, Ty_Int()); } } else if (3 < oper && oper < 10) { if (oper == 4 || oper == 5) {/*check record type can be nil*/ if (left.ty->kind == Ty_record && right.ty->kind == Ty_nil) { return expTy(NULL, Ty_Int()); } if (left.ty->kind == Ty_nil && right.ty->kind == Ty_record) { return expTy(NULL, Ty_Int()); } } if(left.ty->kind != Ty_int && left.ty->kind != Ty_double && left.ty->kind != Ty_string){ EM_error(e->u.op.left->pos, "int or double or record-nil required"); } if (right.ty->kind != Ty_int && right.ty->kind != Ty_double && right.ty->kind !=Ty_string) { EM_error(e->u.op.right->pos, "int or double or record-nil required"); } return expTy(NULL, Ty_Int()); } else { assert(0); } case A_ifExp: final = transExp(level, v, t, e->u.iff.test); final2 = transExp(level, v, t, e->u.iff.then); if (e->u.iff.elsee) { /*no else-part*/ final3 = transExp(level, v, t, e->u.iff.elsee); if (final.ty->kind != Ty_int){ EM_error(e->u.iff.test->pos, "int required"); } else if(!ty_match(final2.ty, final3.ty)) {
//here static struct expty transExp(Tr_level level,Tr_exp breakk,S_table v, S_table t, A_exp e){ A_oper oper; struct expty left,right,final,final2,final3,final4,final5,lo,hi; A_expList list; A_decList decs; E_enventry callinfo; Ty_ty recty,arrayty; if (!e) { return expTy(Tr_noExp(), Ty_Void()); } switch(e->kind){ case A_varExp: return transVar(level,breakk,v,t,e->u.var); break; case A_nilExp: return expTy(Tr_nilExp(),Ty_Nil()); break; case A_callExp: callinfo =S_look(v,e->u.call.func); A_expList args=NULL; Tr_expList argList=NULL; for (args=e->u.call.args;args;args=args->tail){ struct expty arg = transExp(level, breakk, v, t, args->head); Tr_expList_prepend(arg.exp, &argList); } Tr_exp trans = Tr_noExp(); if (callinfo&&callinfo->kind==E_funEntry) { trans = Tr_callExp(callinfo->u.fun.label, callinfo->u.fun.level, level, &argList); //检查参数个数、类型匹配 if (args_match(level, breakk, v, t, e->u.call.args, callinfo->u.fun.formals, e)) {/*check params is matched*/ if (callinfo->u.fun.result) { return expTy(trans, actual_ty(callinfo->u.fun.result)); } } /* if (args_match(level,v,t,e->u.call.args,callinfo->u.fun.formals,e)){ return expTy(NULL, actual_ty(callinfo->u.fun.result)); }else{ return expTy(NULL, Ty_Void()); } */ }else { EM_error(e->pos, "undefined function %s\n", S_name(e->u.call.func)); } return expTy(trans, Ty_Void()); break; case A_recordExp: recty = actual_ty(S_look(t, e->u.record.typ)); if (!recty) { /*cant find record-type in table tenv*/ EM_error(e->pos, "undefined type %s (debug recordExp)", S_name(e->u.record.typ)); }else{ if (recty->kind != Ty_record){ EM_error(e->pos, "%s is not a record type", S_name(e->u.record.typ)); return expTy(Tr_noExp(), Ty_Record(NULL)); } if (efields_match(level,breakk,v, t, recty, e)) {/*check record field is matched*/ Tr_expList l=NULL; int n=0; A_efieldList el; for (el=e->u.record.fields;el;el=el->tail,n++){ struct expty val = transExp(level, breakk, v, t, el->head->exp); Tr_expList_prepend(val.exp,&l); } return expTy(Tr_recordExp(n, l), recty); } } return expTy(Tr_noExp(), Ty_Record(NULL)); break; case A_arrayExp: arrayty=actual_ty(S_look(t,e->u.array.typ)); if (!arrayty) { EM_error(e->pos, "undeined array type %s", S_name(e->u.array.typ)); return expTy(Tr_noExp(), Ty_Array(NULL)); } if (arrayty->kind != Ty_array) { EM_error(e->pos, "%s is not a array type", S_name(e->u.array.typ)); return expTy(Tr_noExp(), Ty_Array(NULL)); } final2 = transExp(level,breakk,v, t, e->u.array.size);//数组大小 表达式 final3 = transExp(level,breakk,v, t, e->u.array.init);//数组初始化 表达式 if (final2.ty->kind != Ty_int) { EM_error(e->pos, "array size should be int %s", S_name(e->u.array.typ)); }else if (!ty_match(final3.ty, arrayty->u.array)){ EM_error(e->pos, "unmatched array type in %s", S_name(e->u.array.typ)); } else { return expTy(Tr_arrayExp(final2.exp, final3.exp), arrayty); } return expTy(Tr_noExp(), Ty_Int()); break; case A_seqExp:{ Tr_expList l = NULL; list = e->u.seq; struct expty seqone; if (!list) { return expTy(Tr_noExp(), Ty_Void()); } /*while (list->tail) { seqone= transExp(level,breakk,v, t, list->head); Tr_expList_prepend(seqone.exp, &l); list = list->tail; } */ for (; list; list = list->tail) { seqone = transExp(level, breakk, v, t, list->head); Tr_expList_prepend(seqone.exp, &l); } printf("A_seqExp\n"); return expTy(Tr_seqExp(l), seqone.ty); } break; case A_whileExp: final = transExp(level,breakk,v, t, e->u.whilee.test); if (final.ty->kind != Ty_int) { EM_error(e->pos, "int required"); } Tr_exp done = Tr_doneExp(); struct expty body=transExp(level,done,v, t, e->u.whilee.body); return expTy(Tr_whileExp(final.exp, body.exp, done), Ty_Void()); break; case A_assignExp: final4 = transVar(level,breakk,v, t, e->u.assign.var); final5 = transExp(level,breakk,v, t, e->u.assign.exp); if (!ty_match(final4.ty, final5.ty)) { EM_error(e->pos, "unmatched assign exp"); } return expTy(Tr_assignExp(final4.exp, final5.exp), Ty_Void()); case A_breakExp: if (!breakk) return expTy(Tr_noExp(), Ty_Void()); return expTy(Tr_breakExp(breakk), Ty_Void()); case A_forExp:{ /* struct expty lo = transExp(level,v, t, e->u.forr.lo); struct expty hi = transExp(level,v, t, e->u.forr.hi); struct expty body; if (lo.ty != Ty_Int() || hi.ty != Ty_Int()) { EM_error(e->pos, "low or high range type is not integer"); } S_beginScope(v); transDec(level,v, t, A_VarDec(e->pos, e->u.forr.var, S_Symbol("int"), e->u.forr.lo)); body = transExp(level,v, t, e->u.forr.body); S_endScope(v); return expTy(NULL, Ty_Void()); */ EM_error(e->pos, "\nsome one said for is better than while\nmake them unhappy \nahahaha"); return expTy(Tr_noExp(), Ty_Int()); } break; case A_letExp:{ Tr_expList l = NULL; S_beginScope(v); S_beginScope(t); for (decs=e->u.let.decs;decs;decs=decs->tail){ //transDec(level,v,t,decs->head); ; Tr_expList_prepend(transDec(level, breakk, v, t, decs->head), &l); } final=transExp(level,breakk,v,t,e->u.let.body); Tr_expList_prepend(final.exp, &l); S_endScope(t); S_endScope(v); printf("A_letExp\n"); return expTy(Tr_seqExp(l), final.ty);; } break; case A_opExp:{ A_oper oper = e->u.op.oper; struct expty left = transExp(level, breakk, v, t, e->u.op.left); struct expty right = transExp(level, breakk, v, t, e->u.op.right); if (0 <= oper && oper < 4) {/* check +,-,*,/ */ if (left.ty->kind != Ty_int ){ EM_error(e->u.op.left->pos, "int or double required(op)"); } else if (left.ty->kind == Ty_int && right.ty->kind == Ty_int) { return expTy(Tr_arithExp(oper, left.exp, right.exp), Ty_Int()); } return expTy(Tr_noExp(), Ty_Int()); } else if (3 < oper && oper < 10) { Tr_exp translation = Tr_noExp(); if (oper == 4 || oper == 5) {/*check record type can be nil(=, <>)*/ switch(left.ty->kind) { case Ty_int: //case Ty_double:/*see is double query like int TODO*/ if (right.ty->kind == Ty_int ) translation = Tr_eqExp(oper, left.exp, right.exp); else {EM_error(e->u.op.right->pos, "unexpected type in comparsion");} break; case Ty_string: if (ty_match(right.ty, left.ty)) translation = Tr_eqStringExp(oper, left.exp, right.exp); else {EM_error(e->u.op.right->pos, "unexpected type in comparsion");} break; case Ty_array: if (ty_match(right.ty, left.ty)) translation = Tr_eqRef(oper, left.exp, right.exp); else {EM_error(e->u.op.right->pos, "unexpected type in comparsion");} break; case Ty_record: if (ty_match(right.ty, left.ty) || right.ty->kind == Ty_nil) translation = Tr_eqRef(oper, left.exp, right.exp); else {EM_error(e->u.op.right->pos, "unexpected type in comparsion");} break; default: EM_error(e->u.op.right->pos, "unexpected expression in comparsion"); } return expTy(translation, Ty_Int()); } else { switch(left.ty->kind) { //case Ty_double: case Ty_int: if ( right.ty->kind == Ty_int) translation = Tr_relExp(oper, left.exp, right.exp); else {EM_error(e->u.op.right->pos, "unexpected type in comparsion");} break; case Ty_string: if (right.ty->kind == Ty_string) translation = Tr_eqStringExp(oper, left.exp, right.exp); else {EM_error(e->u.op.right->pos, "unexpected type in comparsion");} break; default: EM_error(e->u.op.right->pos, "unexpected type in comparsion"); } return expTy(translation, Ty_Int()); } } else { assert(0); } } break; case A_ifExp: final = transExp(level,breakk,v, t, e->u.iff.test); final2 = transExp(level,breakk,v, t, e->u.iff.then); //final3 = {NULL, NULL}; if (e->u.iff.elsee) { /*no else-part*/ final3 = transExp(level,breakk,v, t, e->u.iff.elsee); if (final.ty->kind != Ty_int){ EM_error(e->u.iff.test->pos, "int required"); } else if(!ty_match(final2.ty, final3.ty)) {
static GLuint emit_texenv( struct i915_fragment_program *p, int unit ) { struct gl_texture_unit *texUnit = &p->ctx->Texture.Unit[unit]; GLenum envMode = texUnit->EnvMode; struct gl_texture_object *tObj = texUnit->_Current; GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; GLuint saturate = unit < p->last_tex_stage ? A0_DEST_SATURATE : 0; switch(envMode) { case GL_BLEND: { const int cf = get_source(p, GL_PREVIOUS, unit); const int cc = get_source(p, GL_CONSTANT, unit); const int cs = get_source(p, GL_TEXTURE, unit); const int out = get_dest(p, unit); if (format == GL_INTENSITY) { /* cv = cf(1 - cs) + cc.cs * cv = cf - cf.cs + cc.cs */ /* u[2] = MAD( -cf * cs + cf ) * cv = MAD( cc * cs + u[2] ) */ i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0, negate(cf,1,1,1,1), cs, cf ); i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate, cc, cs, out ); return out; } else { /* cv = cf(1 - cs) + cc.cs * cv = cf - cf.cs + cc.cs * av = af.as */ /* u[2] = MAD( cf.-x-y-zw * cs.xyzw + cf.xyz0 ) * oC = MAD( cc.xyz0 * cs.xyz0 + u[2].xyzw ) */ i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0, negate(cf,1,1,1,0), cs, swizzle(cf,X,Y,Z,ZERO) ); i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate, swizzle(cc,X,Y,Z,ZERO), swizzle(cs,X,Y,Z,ZERO), out ); return out; } } case GL_DECAL: { if (format == GL_RGB || format == GL_RGBA) { int cf = get_source( p, GL_PREVIOUS, unit ); int cs = get_source( p, GL_TEXTURE, unit ); int out = get_dest(p, unit); /* cv = cf(1-as) + cs.as * cv = cf.(-as) + cf + cs.as * av = af */ /* u[2] = mad( cf.xyzw * cs.-w-w-w1 + cf.xyz0 ) * oc = mad( cs.xyz0 * cs.www0 + u[2].xyzw ) */ i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0, cf, negate(swizzle(cs,W,W,W,ONE),1,1,1,0), swizzle(cf,X,Y,Z,ZERO) ); i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate, swizzle(cs,X,Y,Z,ZERO), swizzle(cs,W,W,W,ZERO), out ); return out; } else { return get_source( p, GL_PREVIOUS, unit ); } } case GL_REPLACE: { const int cs = get_source( p, GL_TEXTURE, unit ); /* saturated */ switch (format) { case GL_ALPHA: { const int cf = get_source( p, GL_PREVIOUS, unit ); /* saturated */ i915_emit_arith( p, A0_MOV, cs, A0_DEST_CHANNEL_XYZ, 0, cf, 0, 0 ); return cs; } case GL_RGB: case GL_LUMINANCE: { const int cf = get_source( p, GL_PREVIOUS, unit ); /* saturated */ i915_emit_arith( p, A0_MOV, cs, A0_DEST_CHANNEL_W, 0, cf, 0, 0 ); return cs; } default: return cs; } } case GL_MODULATE: { const int cf = get_source( p, GL_PREVIOUS, unit ); const int cs = get_source( p, GL_TEXTURE, unit ); const int out = get_dest(p, unit); switch (format) { case GL_ALPHA: i915_emit_arith( p, A0_MUL, out, A0_DEST_CHANNEL_ALL, saturate, swizzle(cs, ONE, ONE, ONE, W), cf, 0 ); break; default: i915_emit_arith( p, A0_MUL, out, A0_DEST_CHANNEL_ALL, saturate, cs, cf, 0 ); break; } return out; } case GL_ADD: { int cf = get_source( p, GL_PREVIOUS, unit ); int cs = get_source( p, GL_TEXTURE, unit ); const int out = get_dest( p, unit ); if (format == GL_INTENSITY) { /* output-color.rgba = add( incoming, u[1] ) */ i915_emit_arith( p, A0_ADD, out, A0_DEST_CHANNEL_ALL, saturate, cs, cf, 0 ); return out; } else { /* cv.xyz = cf.xyz + cs.xyz * cv.w = cf.w * cs.w * * cv.xyzw = MAD( cf.111w * cs.xyzw + cf.xyz0 ) */ i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate, swizzle(cf,ONE,ONE,ONE,W), cs, swizzle(cf,X,Y,Z,ZERO) ); return out; } break; } case GL_COMBINE: { GLuint rgb_shift, alpha_shift, out, shift; GLuint dest = get_dest(p, unit); /* The EXT version of the DOT3 extension does not support the * scale factor, but the ARB version (and the version in OpenGL * 1.3) does. */ switch (texUnit->Combine.ModeRGB) { case GL_DOT3_RGB_EXT: alpha_shift = texUnit->Combine.ScaleShiftA; rgb_shift = 0; break; case GL_DOT3_RGBA_EXT: alpha_shift = 0; rgb_shift = 0; break; default: rgb_shift = texUnit->Combine.ScaleShiftRGB; alpha_shift = texUnit->Combine.ScaleShiftA; break; } /* Emit the RGB and A combine ops */ if (texUnit->Combine.ModeRGB == texUnit->Combine.ModeA && args_match( texUnit )) { out = emit_combine( p, dest, A0_DEST_CHANNEL_ALL, saturate, unit, texUnit->Combine.ModeRGB, texUnit->Combine.SourceRGB, texUnit->Combine.OperandRGB ); } else if (texUnit->Combine.ModeRGB == GL_DOT3_RGBA_EXT || texUnit->Combine.ModeRGB == GL_DOT3_RGBA) { out = emit_combine( p, dest, A0_DEST_CHANNEL_ALL, saturate, unit, texUnit->Combine.ModeRGB, texUnit->Combine.SourceRGB, texUnit->Combine.OperandRGB ); } else { /* Need to do something to stop from re-emitting identical * argument calculations here: */ out = emit_combine( p, dest, A0_DEST_CHANNEL_XYZ, saturate, unit, texUnit->Combine.ModeRGB, texUnit->Combine.SourceRGB, texUnit->Combine.OperandRGB ); out = emit_combine( p, dest, A0_DEST_CHANNEL_W, saturate, unit, texUnit->Combine.ModeA, texUnit->Combine.SourceA, texUnit->Combine.OperandA ); } /* Deal with the final shift: */ if (alpha_shift || rgb_shift) { if (rgb_shift == alpha_shift) { shift = i915_emit_const1f(p, 1<<rgb_shift); shift = swizzle(shift,X,X,X,X); } else { shift = i915_emit_const2f(p, 1<<rgb_shift, 1<<alpha_shift); shift = swizzle(shift,X,X,X,Y); } return i915_emit_arith( p, A0_MUL, dest, A0_DEST_CHANNEL_ALL, saturate, out, shift, 0 ); } return out; } default: return get_source(p, GL_PREVIOUS, 0); } }