blob: c0874b143933787ce3992ca999a13d00f1c39278 [file] [log] [blame]
drhf2bc0132004-10-04 13:19:23 +00001#!/usr/bin/awk -f
2#
drh722e95a2004-10-25 20:33:44 +00003# Generate the file opcodes.h.
4#
drhf2bc0132004-10-04 13:19:23 +00005# This AWK script scans a concatenation of the parse.h output file from the
6# parser and the vdbe.c source file in order to generate the opcodes numbers
7# for all opcodes.
8#
9# The lines of the vdbe.c that we are interested in are of the form:
10#
11# case OP_aaaa: /* same as TK_bbbbb */
12#
13# The TK_ comment is optional. If it is present, then the value assigned to
14# the OP_ is the same as the TK_ value. If missing, the OP_ value is assigned
15# a small integer that is different from every other OP_ value.
16#
drh0ed4fcd2006-01-26 14:29:58 +000017# We go to the trouble of making some OP_ values the same as TK_ values
drh722e95a2004-10-25 20:33:44 +000018# as an optimization. During parsing, things like expression operators
19# are coded with TK_ values such as TK_ADD, TK_DIVIDE, and so forth. Later
20# during code generation, we need to generate corresponding opcodes like
21# OP_Add and OP_Divide. By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide,
drh0ed4fcd2006-01-26 14:29:58 +000022# code to translate from one to the other is avoided. This makes the
drh722e95a2004-10-25 20:33:44 +000023# code generator run (infinitesimally) faster and more importantly it makes
drh0ed4fcd2006-01-26 14:29:58 +000024# the library footprint smaller.
drh722e95a2004-10-25 20:33:44 +000025#
drhfa3b19e2005-11-24 22:22:29 +000026# This script also scans for lines of the form:
27#
28# case OP_aaaa: /* no-push */
29#
30# When the no-push comment is found on an opcode, it means that that
drh0ed4fcd2006-01-26 14:29:58 +000031# opcode does not leave a result on the stack. By identifying which
drhfa3b19e2005-11-24 22:22:29 +000032# opcodes leave results on the stack it is possible to determine a
33# much smaller upper bound on the size of the stack. This allows
34# a smaller stack to be allocated, which is important to embedded
35# systems with limited memory space. This script generates a series
36# of "NOPUSH_MASK" defines that contain bitmaps of opcodes that leave
37# results on the stack. The NOPUSH_MASK defines are used in vdbeaux.c
38# to help determine the maximum stack size.
39#
drhf2bc0132004-10-04 13:19:23 +000040
danielk1977bc04f852005-03-29 08:26:13 +000041
drhf2bc0132004-10-04 13:19:23 +000042# Remember the TK_ values from the parse.h file
43/^#define TK_/ {
44 tk[$2] = $3
45}
46
47# Scan for "case OP_aaaa:" lines in the vdbe.c file
48/^case OP_/ {
49 name = $2
drhb726ee62005-09-05 20:35:25 +000050 sub(/:/,"",name)
51 sub("\r","",name)
drhf2bc0132004-10-04 13:19:23 +000052 op[name] = -1
danielk1977bc04f852005-03-29 08:26:13 +000053 for(i=3; i<NF; i++){
drhf2bc0132004-10-04 13:19:23 +000054 if($i=="same" && $(i+1)=="as"){
danielk1977bc04f852005-03-29 08:26:13 +000055 sym = $(i+2)
56 sub(/,/,"",sym)
57 op[name] = tk[sym]
drhf2bc0132004-10-04 13:19:23 +000058 used[op[name]] = 1
danielk1977bc04f852005-03-29 08:26:13 +000059 sameas[op[name]] = sym
60 }
danielk19777a5147c2005-03-29 13:07:00 +000061 if($i=="no-push"){
62 nopush[name] = 1
drhf2bc0132004-10-04 13:19:23 +000063 }
64 }
65}
66
67# Assign numbers to all opcodes and output the result.
68END {
69 cnt = 0
drhdaa28ff2004-12-10 17:17:18 +000070 max = 0
drhb327f772004-10-06 15:03:57 +000071 print "/* Automatically generated. Do not edit */"
72 print "/* See the mkopcodeh.awk script for details */"
drhf2bc0132004-10-04 13:19:23 +000073 for(name in op){
74 if( op[name]<0 ){
75 cnt++
76 while( used[cnt] ) cnt++
77 op[name] = cnt
78 }
drhdaa28ff2004-12-10 17:17:18 +000079 used[op[name]] = 1;
80 if( op[name]>max ) max = op[name]
drh0602c2e2005-01-21 17:07:22 +000081 printf "#define %-25s %15d", name, op[name]
82 if( sameas[op[name]] ) {
danielk197724c8ab82005-02-09 01:40:23 +000083 printf " /* same as %-12s*/", sameas[op[name]]
drh0602c2e2005-01-21 17:07:22 +000084 }
85 printf "\n"
86
drhf2bc0132004-10-04 13:19:23 +000087 }
drhdaa28ff2004-12-10 17:17:18 +000088 seenUnused = 0;
89 for(i=1; i<max; i++){
90 if( !used[i] ){
91 if( !seenUnused ){
92 printf "\n/* The following opcode values are never used */\n"
93 seenUnused = 1
94 }
drh0602c2e2005-01-21 17:07:22 +000095 printf "#define %-25s %15d\n", sprintf( "OP_NotUsed_%-3d", i ), i
drhdaa28ff2004-12-10 17:17:18 +000096 }
97 }
danielk1977bc04f852005-03-29 08:26:13 +000098
99 # Generate the 10 16-bit bitmasks used by function opcodeUsesStack()
100 # in vdbeaux.c. See comments in that function for details.
101 #
danielk19777a5147c2005-03-29 13:07:00 +0000102 nopush[0] = 0 # 0..15
103 nopush[1] = 0 # 16..31
104 nopush[2] = 0 # 32..47
105 nopush[3] = 0 # 48..63
106 nopush[4] = 0 # 64..79
107 nopush[5] = 0 # 80..95
108 nopush[6] = 0 # 96..111
109 nopush[7] = 0 # 112..127
110 nopush[8] = 0 # 128..143
111 nopush[9] = 0 # 144..159
danielk1977bc04f852005-03-29 08:26:13 +0000112 for(name in op){
danielk19777a5147c2005-03-29 13:07:00 +0000113 if( nopush[name] ){
danielk1977bc04f852005-03-29 08:26:13 +0000114 n = op[name]
115 j = n%16
116 i = ((n - j)/16)
danielk19777a5147c2005-03-29 13:07:00 +0000117 nopush[i] = nopush[i] + (2^j)
danielk1977bc04f852005-03-29 08:26:13 +0000118 }
119 }
120 printf "\n"
drh0ed4fcd2006-01-26 14:29:58 +0000121 print "/* Opcodes that are guaranteed to never push a value onto the stack"
122 print "** contain a 1 their corresponding position of the following mask"
123 print "** set. See the opcodeNoPush() function in vdbeaux.c */"
danielk1977bc04f852005-03-29 08:26:13 +0000124 for(i=0; i<10; i++){
drh0ed4fcd2006-01-26 14:29:58 +0000125 printf "#define NOPUSH_MASK_%d 0x%04x\n", i, nopush[i]
danielk1977bc04f852005-03-29 08:26:13 +0000126 }
drhf2bc0132004-10-04 13:19:23 +0000127}