mojoshader_assembler.c
changeset 481 7d26f6086725
parent 480 e7a7822fb38b
child 482 3f740f25bd7e
equal deleted inserted replaced
480:e7a7822fb38b 481:7d26f6086725
  1197 
  1197 
  1198     return 0;
  1198     return 0;
  1199 } // parse_condition
  1199 } // parse_condition
  1200 
  1200 
  1201 
  1201 
       
  1202 static inline int valid_instruction_char(const char ch)
       
  1203 {
       
  1204     return ( ((ch >= 'A') && (ch <= 'Z')) ||
       
  1205              ((ch >= 'a') && (ch <= 'z')) ||
       
  1206              ((ch >= '0') && (ch <= '9')) );
       
  1207 } // valid_instruction_char
       
  1208 
       
  1209 
  1202 static int parse_instruction_token(Context *ctx)
  1210 static int parse_instruction_token(Context *ctx)
  1203 {
  1211 {
  1204     int coissue = 0;
  1212     int coissue = 0;
  1205     int predicated = 0;
  1213     int predicated = 0;
       
  1214     char opstr[32];
  1206 
  1215 
  1207     if (strcmp(ctx->token, "+") == 0)
  1216     if (strcmp(ctx->token, "+") == 0)
  1208     {
  1217     {
  1209         if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
  1218         if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
  1210             return FAIL;
  1219             return FAIL;
  1211         coissue = 1;
  1220         coissue = 1;
  1212     } // if
  1221     } // if
  1213 
  1222 
       
  1223     // All this tapdance is because some instructions mix letters and numbers,
       
  1224     //  like "dp4" or "texm3x2depth" and the tokenizer splits words and digits
       
  1225     //  into separate tokens, which makes parsing registers ("c31") easier.
       
  1226     opstr[0] = '\0';
       
  1227     while (1)
       
  1228     {
       
  1229         if ( (strlen(opstr) + strlen(ctx->token)) >= (sizeof (opstr)-1) )
       
  1230             return fail(ctx, "Expected instruction");
       
  1231 
       
  1232         char *ptr;
       
  1233         for (ptr = ctx->token; *ptr != '\0'; ptr++)
       
  1234         {
       
  1235             if (!valid_instruction_char(*ptr))
       
  1236                 break;
       
  1237         } // for
       
  1238 
       
  1239         if ((ptr == ctx->token) || (*ptr != '\0'))
       
  1240         {
       
  1241             pushback(ctx);  // an invalid char or EOS in this token.
       
  1242             break;
       
  1243         } // if
       
  1244 
       
  1245         strcat(opstr, ctx->token);
       
  1246 
       
  1247         if (nexttoken(ctx, 0, 0, 1, 1) == FAIL)
       
  1248             return FAIL;
       
  1249     } // while
       
  1250 
  1214     int i;
  1251     int i;
  1215     int valid_opcode = 0;
  1252     int valid_opcode = 0;
  1216     const Instruction *instruction = NULL;
  1253     const Instruction *instruction = NULL;
  1217     for (i = 0; i < STATICARRAYLEN(instructions); i++)
  1254     for (i = 0; i < STATICARRAYLEN(instructions); i++)
  1218     {
  1255     {
  1219         instruction = &instructions[i];
  1256         instruction = &instructions[i];
  1220         if (instruction->opcode_string == NULL)
  1257         if (instruction->opcode_string == NULL)
  1221             continue;  // skip this.
  1258             continue;  // skip this.
  1222         else if (strcasecmp(ctx->token, instruction->opcode_string) != 0)
  1259         else if (strcasecmp(opstr, instruction->opcode_string) != 0)
  1223             continue;  // not us.
  1260             continue;  // not us.
  1224         valid_opcode = 1;
  1261         valid_opcode = 1;
  1225         break;
  1262         break;
  1226     } // for
  1263     } // for
  1227 
  1264 
  1228     uint32 opcode = (uint32) i;
  1265     uint32 opcode = (uint32) i;
  1229     uint32 controls = 0;
  1266     uint32 controls = 0;
  1230 
  1267 
  1231     if (!valid_opcode)
  1268     if (!valid_opcode)
  1232         return failf(ctx, "Unknown instruction '%s'", ctx->token);
  1269         return failf(ctx, "Unknown instruction '%s'", opstr);
  1233 
  1270 
  1234     // This might need to be IFC instead of IF.
  1271     // This might need to be IFC instead of IF.
  1235     if (strcmp(instruction->opcode_string, "IF") == 0)
  1272     if (strcmp(instruction->opcode_string, "IF") == 0)
  1236     {
  1273     {
  1237         if (parse_condition(ctx, &controls))
  1274         if (parse_condition(ctx, &controls))