comparison lwasm/lwasm.c @ 241:d0e9dbe9afbe

Add new heuristic for resolving instruction sizes. Add new heuristic for resolving instruction sizes. This applies to the the decision between extended and base page addressing by calculating the range of possible addresses (if reasonably knowable) and deciding on whether to force extended addressing based on that. (If the whole range is outside the direct page, extended addressing is required.)
author William Astle <lost@l-w.ca>
date Sun, 23 Sep 2012 13:06:43 -0600
parents 41d64951eb32
children 1f1a28b797e1
comparison
equal deleted inserted replaced
240:41d64951eb32 241:d0e9dbe9afbe
986 return NULL; 986 return NULL;
987 } 987 }
988 debug_message(as, 250, "Returning expression"); 988 debug_message(as, 250, "Returning expression");
989 return e; 989 return e;
990 } 990 }
991
992 struct range_data
993 {
994 int min;
995 int max;
996 asmstate_t *as;
997 };
998 int lwasm_calculate_range(asmstate_t *as, lw_expr_t expr, int *min, int *max);
999 int lwasm_calculate_range_tf(lw_expr_t e, void *info)
1000 {
1001 struct range_data *rd = info;
1002 int i;
1003
1004 if (lw_expr_istype(e, lw_expr_type_int))
1005 {
1006 i = lw_expr_intval(e);
1007 rd -> min += i;
1008 rd -> max += i;
1009 return 0;
1010 }
1011
1012 if (lw_expr_istype(e, lw_expr_type_special))
1013 {
1014 line_t *l;
1015 if (lw_expr_specint(e) != lwasm_expr_linelen)
1016 {
1017 rd -> min = -1;
1018 return -1;
1019 }
1020 l = (line_t *)lw_expr_specptr(e);
1021 if (l -> len == -1)
1022 {
1023 rd -> min += l -> minlen;
1024 rd -> max += l -> maxlen;
1025 }
1026 else
1027 {
1028 rd -> min += l -> len;
1029 }
1030 return 0;
1031 }
1032
1033 if (lw_expr_istype(e, lw_expr_type_var))
1034 {
1035 lw_expr_t te;
1036 te = lw_expr_copy(e);
1037 lwasm_reduce_expr(rd -> as, te);
1038 if (lw_expr_istype(te, lw_expr_type_int))
1039 {
1040 i = lw_expr_intval(te);
1041 rd -> min += i;
1042 rd -> max += i;
1043 }
1044 else
1045 {
1046 rd -> min = -1;
1047 }
1048 lw_expr_destroy(te);
1049 if (rd -> min == -1)
1050 return -1;
1051 return 0;
1052 }
1053
1054 if (lw_expr_istype(e, lw_expr_type_oper))
1055 {
1056 if (lw_expr_whichop(e) == lw_expr_oper_plus)
1057 return 0;
1058 rd -> min = -1;
1059 return -1;
1060 }
1061
1062 rd -> min = -1;
1063 return -1;
1064 }
1065
1066 int lwasm_calculate_range(asmstate_t *as, lw_expr_t expr, int *min, int *max)
1067 {
1068 struct range_data rd;
1069
1070 rd.min = 0;
1071 rd.max = 0;
1072 rd.as = as;
1073
1074 lw_expr_testterms(expr, lwasm_calculate_range_tf, (void *)&rd);
1075 *min = rd.min;
1076 *max = rd.max;
1077 if (rd.min == -1)
1078 return -1;
1079 return 0;
1080 }