Mercurial > hg > index.cgi
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 } |