1*9880d681SAndroid Build Coastguard Worker //===- X86DisassemblerTables.h - Disassembler tables ------------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file is part of the X86 Disassembler Emitter. 11*9880d681SAndroid Build Coastguard Worker // It contains the interface of the disassembler tables. 12*9880d681SAndroid Build Coastguard Worker // Documentation for the disassembler emitter in general can be found in 13*9880d681SAndroid Build Coastguard Worker // X86DisasemblerEmitter.h. 14*9880d681SAndroid Build Coastguard Worker // 15*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_UTILS_TABLEGEN_X86DISASSEMBLERTABLES_H 18*9880d681SAndroid Build Coastguard Worker #define LLVM_UTILS_TABLEGEN_X86DISASSEMBLERTABLES_H 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker #include "X86DisassemblerShared.h" 21*9880d681SAndroid Build Coastguard Worker #include "X86ModRMFilters.h" 22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h" 23*9880d681SAndroid Build Coastguard Worker #include <map> 24*9880d681SAndroid Build Coastguard Worker #include <vector> 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker namespace llvm { 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker namespace X86Disassembler { 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker /// DisassemblerTables - Encapsulates all the decode tables being generated by 31*9880d681SAndroid Build Coastguard Worker /// the table emitter. Contains functions to populate the tables as well as 32*9880d681SAndroid Build Coastguard Worker /// to emit them as hierarchical C structures suitable for consumption by the 33*9880d681SAndroid Build Coastguard Worker /// runtime. 34*9880d681SAndroid Build Coastguard Worker class DisassemblerTables { 35*9880d681SAndroid Build Coastguard Worker private: 36*9880d681SAndroid Build Coastguard Worker /// The decoder tables. There is one for each opcode type: 37*9880d681SAndroid Build Coastguard Worker /// [0] one-byte opcodes 38*9880d681SAndroid Build Coastguard Worker /// [1] two-byte opcodes of the form 0f __ 39*9880d681SAndroid Build Coastguard Worker /// [2] three-byte opcodes of the form 0f 38 __ 40*9880d681SAndroid Build Coastguard Worker /// [3] three-byte opcodes of the form 0f 3a __ 41*9880d681SAndroid Build Coastguard Worker /// [4] XOP8 map opcode 42*9880d681SAndroid Build Coastguard Worker /// [5] XOP9 map opcode 43*9880d681SAndroid Build Coastguard Worker /// [6] XOPA map opcode 44*9880d681SAndroid Build Coastguard Worker ContextDecision* Tables[7]; 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker // Table of ModRM encodings. 47*9880d681SAndroid Build Coastguard Worker typedef std::map<std::vector<unsigned>, unsigned> ModRMMapTy; 48*9880d681SAndroid Build Coastguard Worker mutable ModRMMapTy ModRMTable; 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker /// The instruction information table 51*9880d681SAndroid Build Coastguard Worker std::vector<InstructionSpecifier> InstructionSpecifiers; 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Worker /// True if there are primary decode conflicts in the instruction set 54*9880d681SAndroid Build Coastguard Worker bool HasConflicts; 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker /// emitModRMDecision - Emits a table of entries corresponding to a single 57*9880d681SAndroid Build Coastguard Worker /// ModR/M decision. Compacts the ModR/M decision if possible. ModR/M 58*9880d681SAndroid Build Coastguard Worker /// decisions are printed as: 59*9880d681SAndroid Build Coastguard Worker /// 60*9880d681SAndroid Build Coastguard Worker /// { /* struct ModRMDecision */ 61*9880d681SAndroid Build Coastguard Worker /// TYPE, 62*9880d681SAndroid Build Coastguard Worker /// modRMTablennnn 63*9880d681SAndroid Build Coastguard Worker /// } 64*9880d681SAndroid Build Coastguard Worker /// 65*9880d681SAndroid Build Coastguard Worker /// where nnnn is a unique ID for the corresponding table of IDs. 66*9880d681SAndroid Build Coastguard Worker /// TYPE indicates whether the table has one entry that is the same 67*9880d681SAndroid Build Coastguard Worker /// regardless of ModR/M byte, two entries - one for bytes 0x00-0xbf and one 68*9880d681SAndroid Build Coastguard Worker /// for bytes 0xc0-0xff -, or 256 entries, one for each possible byte. 69*9880d681SAndroid Build Coastguard Worker /// nnnn is the number of a table for looking up these values. The tables 70*9880d681SAndroid Build Coastguard Worker /// are written separately so that tables consisting entirely of zeros will 71*9880d681SAndroid Build Coastguard Worker /// not be duplicated. (These all have the name modRMEmptyTable.) A table 72*9880d681SAndroid Build Coastguard Worker /// is printed as: 73*9880d681SAndroid Build Coastguard Worker /// 74*9880d681SAndroid Build Coastguard Worker /// InstrUID modRMTablennnn[k] = { 75*9880d681SAndroid Build Coastguard Worker /// nnnn, /* MNEMONIC */ 76*9880d681SAndroid Build Coastguard Worker /// ... 77*9880d681SAndroid Build Coastguard Worker /// nnnn /* MNEMONIC */ 78*9880d681SAndroid Build Coastguard Worker /// }; 79*9880d681SAndroid Build Coastguard Worker /// 80*9880d681SAndroid Build Coastguard Worker /// @param o1 - The output stream to print the ID table to. 81*9880d681SAndroid Build Coastguard Worker /// @param o2 - The output stream to print the decision structure to. 82*9880d681SAndroid Build Coastguard Worker /// @param i1 - The indentation level to use with stream o1. 83*9880d681SAndroid Build Coastguard Worker /// @param i2 - The indentation level to use with stream o2. 84*9880d681SAndroid Build Coastguard Worker /// @param ModRMTableNum - next table number for adding to ModRMTable. 85*9880d681SAndroid Build Coastguard Worker /// @param decision - The ModR/M decision to emit. This decision has 256 86*9880d681SAndroid Build Coastguard Worker /// entries - emitModRMDecision decides how to compact it. 87*9880d681SAndroid Build Coastguard Worker void emitModRMDecision(raw_ostream &o1, raw_ostream &o2, 88*9880d681SAndroid Build Coastguard Worker unsigned &i1, unsigned &i2, unsigned &ModRMTableNum, 89*9880d681SAndroid Build Coastguard Worker ModRMDecision &decision) const; 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Worker /// emitOpcodeDecision - Emits an OpcodeDecision and all its subsidiary ModR/M 92*9880d681SAndroid Build Coastguard Worker /// decisions. An OpcodeDecision is printed as: 93*9880d681SAndroid Build Coastguard Worker /// 94*9880d681SAndroid Build Coastguard Worker /// { /* struct OpcodeDecision */ 95*9880d681SAndroid Build Coastguard Worker /// /* 0x00 */ 96*9880d681SAndroid Build Coastguard Worker /// { /* struct ModRMDecision */ 97*9880d681SAndroid Build Coastguard Worker /// ... 98*9880d681SAndroid Build Coastguard Worker /// } 99*9880d681SAndroid Build Coastguard Worker /// ... 100*9880d681SAndroid Build Coastguard Worker /// } 101*9880d681SAndroid Build Coastguard Worker /// 102*9880d681SAndroid Build Coastguard Worker /// where the ModRMDecision structure is printed as described in the 103*9880d681SAndroid Build Coastguard Worker /// documentation for emitModRMDecision(). emitOpcodeDecision() passes on a 104*9880d681SAndroid Build Coastguard Worker /// stream and indent level for the UID tables generated by 105*9880d681SAndroid Build Coastguard Worker /// emitModRMDecision(), but does not use them itself. 106*9880d681SAndroid Build Coastguard Worker /// 107*9880d681SAndroid Build Coastguard Worker /// @param o1 - The output stream to print the ID tables generated by 108*9880d681SAndroid Build Coastguard Worker /// emitModRMDecision() to. 109*9880d681SAndroid Build Coastguard Worker /// @param o2 - The output stream for the decision structure itself. 110*9880d681SAndroid Build Coastguard Worker /// @param i1 - The indent level to use with stream o1. 111*9880d681SAndroid Build Coastguard Worker /// @param i2 - The indent level to use with stream o2. 112*9880d681SAndroid Build Coastguard Worker /// @param ModRMTableNum - next table number for adding to ModRMTable. 113*9880d681SAndroid Build Coastguard Worker /// @param decision - The OpcodeDecision to emit along with its subsidiary 114*9880d681SAndroid Build Coastguard Worker /// structures. 115*9880d681SAndroid Build Coastguard Worker void emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, 116*9880d681SAndroid Build Coastguard Worker unsigned &i1, unsigned &i2, unsigned &ModRMTableNum, 117*9880d681SAndroid Build Coastguard Worker OpcodeDecision &decision) const; 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker /// emitContextDecision - Emits a ContextDecision and all its subsidiary 120*9880d681SAndroid Build Coastguard Worker /// Opcode and ModRMDecisions. A ContextDecision is printed as: 121*9880d681SAndroid Build Coastguard Worker /// 122*9880d681SAndroid Build Coastguard Worker /// struct ContextDecision NAME = { 123*9880d681SAndroid Build Coastguard Worker /// { /* OpcodeDecisions */ 124*9880d681SAndroid Build Coastguard Worker /// /* IC */ 125*9880d681SAndroid Build Coastguard Worker /// { /* struct OpcodeDecision */ 126*9880d681SAndroid Build Coastguard Worker /// ... 127*9880d681SAndroid Build Coastguard Worker /// }, 128*9880d681SAndroid Build Coastguard Worker /// ... 129*9880d681SAndroid Build Coastguard Worker /// } 130*9880d681SAndroid Build Coastguard Worker /// } 131*9880d681SAndroid Build Coastguard Worker /// 132*9880d681SAndroid Build Coastguard Worker /// NAME is the name of the ContextDecision (typically one of the four names 133*9880d681SAndroid Build Coastguard Worker /// ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, THREEBYTE3A_SYM from 134*9880d681SAndroid Build Coastguard Worker /// X86DisassemblerDecoderCommon.h). 135*9880d681SAndroid Build Coastguard Worker /// IC is one of the contexts in InstructionContext. There is an opcode 136*9880d681SAndroid Build Coastguard Worker /// decision for each possible context. 137*9880d681SAndroid Build Coastguard Worker /// The OpcodeDecision structures are printed as described in the 138*9880d681SAndroid Build Coastguard Worker /// documentation for emitOpcodeDecision. 139*9880d681SAndroid Build Coastguard Worker /// 140*9880d681SAndroid Build Coastguard Worker /// @param o1 - The output stream to print the ID tables generated by 141*9880d681SAndroid Build Coastguard Worker /// emitModRMDecision() to. 142*9880d681SAndroid Build Coastguard Worker /// @param o2 - The output stream to print the decision structure to. 143*9880d681SAndroid Build Coastguard Worker /// @param i1 - The indent level to use with stream o1. 144*9880d681SAndroid Build Coastguard Worker /// @param i2 - The indent level to use with stream o2. 145*9880d681SAndroid Build Coastguard Worker /// @param ModRMTableNum - next table number for adding to ModRMTable. 146*9880d681SAndroid Build Coastguard Worker /// @param decision - The ContextDecision to emit along with its subsidiary 147*9880d681SAndroid Build Coastguard Worker /// structures. 148*9880d681SAndroid Build Coastguard Worker /// @param name - The name for the ContextDecision. 149*9880d681SAndroid Build Coastguard Worker void emitContextDecision(raw_ostream &o1, raw_ostream &o2, 150*9880d681SAndroid Build Coastguard Worker unsigned &i1, unsigned &i2, unsigned &ModRMTableNum, 151*9880d681SAndroid Build Coastguard Worker ContextDecision &decision, const char* name) const; 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker /// emitInstructionInfo - Prints the instruction specifier table, which has 154*9880d681SAndroid Build Coastguard Worker /// one entry for each instruction, and contains name and operand 155*9880d681SAndroid Build Coastguard Worker /// information. This table is printed as: 156*9880d681SAndroid Build Coastguard Worker /// 157*9880d681SAndroid Build Coastguard Worker /// struct InstructionSpecifier CONTEXTS_SYM[k] = { 158*9880d681SAndroid Build Coastguard Worker /// { 159*9880d681SAndroid Build Coastguard Worker /// /* nnnn */ 160*9880d681SAndroid Build Coastguard Worker /// "MNEMONIC", 161*9880d681SAndroid Build Coastguard Worker /// 0xnn, 162*9880d681SAndroid Build Coastguard Worker /// { 163*9880d681SAndroid Build Coastguard Worker /// { 164*9880d681SAndroid Build Coastguard Worker /// ENCODING, 165*9880d681SAndroid Build Coastguard Worker /// TYPE 166*9880d681SAndroid Build Coastguard Worker /// }, 167*9880d681SAndroid Build Coastguard Worker /// ... 168*9880d681SAndroid Build Coastguard Worker /// } 169*9880d681SAndroid Build Coastguard Worker /// }, 170*9880d681SAndroid Build Coastguard Worker /// }; 171*9880d681SAndroid Build Coastguard Worker /// 172*9880d681SAndroid Build Coastguard Worker /// k is the total number of instructions. 173*9880d681SAndroid Build Coastguard Worker /// nnnn is the ID of the current instruction (0-based). This table 174*9880d681SAndroid Build Coastguard Worker /// includes entries for non-instructions like PHINODE. 175*9880d681SAndroid Build Coastguard Worker /// 0xnn is the lowest possible opcode for the current instruction, used for 176*9880d681SAndroid Build Coastguard Worker /// AddRegFrm instructions to compute the operand's value. 177*9880d681SAndroid Build Coastguard Worker /// ENCODING and TYPE describe the encoding and type for a single operand. 178*9880d681SAndroid Build Coastguard Worker /// 179*9880d681SAndroid Build Coastguard Worker /// @param o - The output stream to which the instruction table should be 180*9880d681SAndroid Build Coastguard Worker /// written. 181*9880d681SAndroid Build Coastguard Worker /// @param i - The indent level for use with the stream. 182*9880d681SAndroid Build Coastguard Worker void emitInstructionInfo(raw_ostream &o, unsigned &i) const; 183*9880d681SAndroid Build Coastguard Worker 184*9880d681SAndroid Build Coastguard Worker /// emitContextTable - Prints the table that is used to translate from an 185*9880d681SAndroid Build Coastguard Worker /// instruction attribute mask to an instruction context. This table is 186*9880d681SAndroid Build Coastguard Worker /// printed as: 187*9880d681SAndroid Build Coastguard Worker /// 188*9880d681SAndroid Build Coastguard Worker /// InstructionContext CONTEXTS_STR[256] = { 189*9880d681SAndroid Build Coastguard Worker /// IC, /* 0x00 */ 190*9880d681SAndroid Build Coastguard Worker /// ... 191*9880d681SAndroid Build Coastguard Worker /// }; 192*9880d681SAndroid Build Coastguard Worker /// 193*9880d681SAndroid Build Coastguard Worker /// IC is the context corresponding to the mask 0x00, and there are 256 194*9880d681SAndroid Build Coastguard Worker /// possible masks. 195*9880d681SAndroid Build Coastguard Worker /// 196*9880d681SAndroid Build Coastguard Worker /// @param o - The output stream to which the context table should be written. 197*9880d681SAndroid Build Coastguard Worker /// @param i - The indent level for use with the stream. 198*9880d681SAndroid Build Coastguard Worker void emitContextTable(raw_ostream &o, uint32_t &i) const; 199*9880d681SAndroid Build Coastguard Worker 200*9880d681SAndroid Build Coastguard Worker /// emitContextDecisions - Prints all four ContextDecision structures using 201*9880d681SAndroid Build Coastguard Worker /// emitContextDecision(). 202*9880d681SAndroid Build Coastguard Worker /// 203*9880d681SAndroid Build Coastguard Worker /// @param o1 - The output stream to print the ID tables generated by 204*9880d681SAndroid Build Coastguard Worker /// emitModRMDecision() to. 205*9880d681SAndroid Build Coastguard Worker /// @param o2 - The output stream to print the decision structures to. 206*9880d681SAndroid Build Coastguard Worker /// @param i1 - The indent level to use with stream o1. 207*9880d681SAndroid Build Coastguard Worker /// @param i2 - The indent level to use with stream o2. 208*9880d681SAndroid Build Coastguard Worker /// @param ModRMTableNum - next table number for adding to ModRMTable. 209*9880d681SAndroid Build Coastguard Worker void emitContextDecisions(raw_ostream &o1, raw_ostream &o2, 210*9880d681SAndroid Build Coastguard Worker unsigned &i1, unsigned &i2, 211*9880d681SAndroid Build Coastguard Worker unsigned &ModRMTableNum) const; 212*9880d681SAndroid Build Coastguard Worker 213*9880d681SAndroid Build Coastguard Worker /// setTableFields - Uses a ModRMFilter to set the appropriate entries in a 214*9880d681SAndroid Build Coastguard Worker /// ModRMDecision to refer to a particular instruction ID. 215*9880d681SAndroid Build Coastguard Worker /// 216*9880d681SAndroid Build Coastguard Worker /// @param decision - The ModRMDecision to populate. 217*9880d681SAndroid Build Coastguard Worker /// @param filter - The filter to use in deciding which entries to populate. 218*9880d681SAndroid Build Coastguard Worker /// @param uid - The unique ID to set matching entries to. 219*9880d681SAndroid Build Coastguard Worker /// @param opcode - The opcode of the instruction, for error reporting. 220*9880d681SAndroid Build Coastguard Worker void setTableFields(ModRMDecision &decision, 221*9880d681SAndroid Build Coastguard Worker const ModRMFilter &filter, 222*9880d681SAndroid Build Coastguard Worker InstrUID uid, 223*9880d681SAndroid Build Coastguard Worker uint8_t opcode); 224*9880d681SAndroid Build Coastguard Worker public: 225*9880d681SAndroid Build Coastguard Worker /// Constructor - Allocates space for the class decisions and clears them. 226*9880d681SAndroid Build Coastguard Worker DisassemblerTables(); 227*9880d681SAndroid Build Coastguard Worker 228*9880d681SAndroid Build Coastguard Worker ~DisassemblerTables(); 229*9880d681SAndroid Build Coastguard Worker 230*9880d681SAndroid Build Coastguard Worker /// emit - Emits the instruction table, context table, and class decisions. 231*9880d681SAndroid Build Coastguard Worker /// 232*9880d681SAndroid Build Coastguard Worker /// @param o - The output stream to print the tables to. 233*9880d681SAndroid Build Coastguard Worker void emit(raw_ostream &o) const; 234*9880d681SAndroid Build Coastguard Worker 235*9880d681SAndroid Build Coastguard Worker /// setTableFields - Uses the opcode type, instruction context, opcode, and a 236*9880d681SAndroid Build Coastguard Worker /// ModRMFilter as criteria to set a particular set of entries in the 237*9880d681SAndroid Build Coastguard Worker /// decode tables to point to a specific uid. 238*9880d681SAndroid Build Coastguard Worker /// 239*9880d681SAndroid Build Coastguard Worker /// @param type - The opcode type (ONEBYTE, TWOBYTE, etc.) 240*9880d681SAndroid Build Coastguard Worker /// @param insnContext - The context to use (IC, IC_64BIT, etc.) 241*9880d681SAndroid Build Coastguard Worker /// @param opcode - The last byte of the opcode (not counting any escape 242*9880d681SAndroid Build Coastguard Worker /// or extended opcodes). 243*9880d681SAndroid Build Coastguard Worker /// @param filter - The ModRMFilter that decides which ModR/M byte values 244*9880d681SAndroid Build Coastguard Worker /// correspond to the desired instruction. 245*9880d681SAndroid Build Coastguard Worker /// @param uid - The unique ID of the instruction. 246*9880d681SAndroid Build Coastguard Worker /// @param is32bit - Instructon is only 32-bit 247*9880d681SAndroid Build Coastguard Worker /// @param ignoresVEX_L - Instruction ignores VEX.L 248*9880d681SAndroid Build Coastguard Worker /// @param AddrSize - Instructions address size 16/32/64. 0 is unspecified 249*9880d681SAndroid Build Coastguard Worker void setTableFields(OpcodeType type, 250*9880d681SAndroid Build Coastguard Worker InstructionContext insnContext, 251*9880d681SAndroid Build Coastguard Worker uint8_t opcode, 252*9880d681SAndroid Build Coastguard Worker const ModRMFilter &filter, 253*9880d681SAndroid Build Coastguard Worker InstrUID uid, 254*9880d681SAndroid Build Coastguard Worker bool is32bit, 255*9880d681SAndroid Build Coastguard Worker bool ignoresVEX_L, 256*9880d681SAndroid Build Coastguard Worker unsigned AddrSize); 257*9880d681SAndroid Build Coastguard Worker 258*9880d681SAndroid Build Coastguard Worker /// specForUID - Returns the instruction specifier for a given unique 259*9880d681SAndroid Build Coastguard Worker /// instruction ID. Used when resolving collisions. 260*9880d681SAndroid Build Coastguard Worker /// 261*9880d681SAndroid Build Coastguard Worker /// @param uid - The unique ID of the instruction. 262*9880d681SAndroid Build Coastguard Worker /// @return - A reference to the instruction specifier. specForUID(InstrUID uid)263*9880d681SAndroid Build Coastguard Worker InstructionSpecifier& specForUID(InstrUID uid) { 264*9880d681SAndroid Build Coastguard Worker if (uid >= InstructionSpecifiers.size()) 265*9880d681SAndroid Build Coastguard Worker InstructionSpecifiers.resize(uid + 1); 266*9880d681SAndroid Build Coastguard Worker 267*9880d681SAndroid Build Coastguard Worker return InstructionSpecifiers[uid]; 268*9880d681SAndroid Build Coastguard Worker } 269*9880d681SAndroid Build Coastguard Worker 270*9880d681SAndroid Build Coastguard Worker // hasConflicts - Reports whether there were primary decode conflicts 271*9880d681SAndroid Build Coastguard Worker // from any instructions added to the tables. 272*9880d681SAndroid Build Coastguard Worker // @return - true if there were; false otherwise. 273*9880d681SAndroid Build Coastguard Worker hasConflicts()274*9880d681SAndroid Build Coastguard Worker bool hasConflicts() { 275*9880d681SAndroid Build Coastguard Worker return HasConflicts; 276*9880d681SAndroid Build Coastguard Worker } 277*9880d681SAndroid Build Coastguard Worker }; 278*9880d681SAndroid Build Coastguard Worker 279*9880d681SAndroid Build Coastguard Worker } // namespace X86Disassembler 280*9880d681SAndroid Build Coastguard Worker 281*9880d681SAndroid Build Coastguard Worker } // namespace llvm 282*9880d681SAndroid Build Coastguard Worker 283*9880d681SAndroid Build Coastguard Worker #endif 284