Files
compiler-explorer/lib/instructionsets.ts
Adrien Bertrand 9e7808b13c Add (e)z80-clang compilers. (#7546)
These clang + LLVM backends are not upstreamed but [a community
effort](https://github.com/CE-Programming/llvm-project/), so it's a bit
customized.

This requires https://github.com/compiler-explorer/infra/pull/1566

_Edit: tested locally, works fine._
2025-04-14 15:17:39 -05:00

241 lines
7.2 KiB
TypeScript

// Copyright (c) 2021, Compiler Explorer Authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
import {InstructionSet} from '../types/instructionsets.js';
type InstructionSetMethod = {
target: string[];
path: string[];
};
export class InstructionSets {
private defaultInstructionset: InstructionSet = 'amd64';
private supported: Record<InstructionSet, InstructionSetMethod>;
constructor() {
this.supported = {
aarch64: {
target: ['aarch64'],
path: ['/aarch64-'],
},
arm32: {
target: ['arm'],
path: ['/arm-'],
},
avr: {
target: ['avr'],
path: ['/avr-'],
},
c6x: {
target: ['c6x'],
path: ['/tic6x-'],
},
dex: {
target: [],
path: [],
},
ebpf: {
target: ['bpf'],
path: ['/bpf-'],
},
ez80: {
target: ['ez80'],
path: [],
},
kvx: {
target: ['kvx'],
path: ['/kvx-', '/k1-'],
},
loongarch: {
target: ['loongarch'],
path: ['/loongarch64-'],
},
m68k: {
target: ['m68k'],
path: ['/m68k-'],
},
mips: {
target: ['mips'],
path: ['/mips', '/mipsel-', '/mips64el-', '/mips64-', '/nanomips-'],
},
mrisc32: {
target: ['mrisc32'],
path: [],
},
msp430: {
target: ['msp430'],
path: ['/msp430-'],
},
powerpc: {
target: ['powerpc', 'ppc64', 'ppc'],
path: ['/powerpc-', '/powerpc64-', '/powerpc64le-'],
},
riscv64: {
target: ['rv64', 'riscv64'],
path: ['/riscv64-'],
},
riscv32: {
target: ['rv32', 'riscv32'],
path: ['/riscv32-'],
},
sh: {
target: ['sh'],
path: ['/sh-'],
},
sparc: {
target: ['sparc', 'sparc64'],
path: ['/sparc-', '/sparc64-'],
},
s390x: {
target: ['s390x'],
path: ['/s390x-'],
},
vax: {
target: ['vax'],
path: ['/vax-'],
},
wasm32: {
target: ['wasm32'],
path: [],
},
wasm64: {
target: ['wasm64'],
path: [],
},
xtensa: {
target: ['xtensa'],
path: ['/xtensa-'],
},
z180: {
target: ['z180'],
path: [],
},
z80: {
target: ['z80'],
path: [],
},
6502: {
target: [],
path: [],
},
wdc65c816: {
target: [],
path: [],
},
core: {
target: [],
path: [],
},
java: {
target: [],
path: [],
},
llvm: {
target: [],
path: [],
},
python: {
target: [],
path: [],
},
ptx: {
target: [],
path: [],
},
x86: {
target: [],
path: [],
},
amd64: {
target: ['x86_64'],
path: ['/x86_64'],
},
evm: {
target: [],
path: [],
},
eravm: {
target: [],
path: [],
},
mos6502: {
target: [],
path: [],
},
sass: {
target: [],
path: [],
},
beam: {
target: [],
path: [],
},
hook: {
target: [],
path: [],
},
spirv: {
target: [],
path: [],
},
};
}
// Return the first spelling of the target for the instruction set,
// or null if data is missing from the 'supported' table.
getInstructionSetTarget(instructionSet: InstructionSet): string | null {
if (!(instructionSet in this.supported)) return null;
if (this.supported[instructionSet].target.length === 0) return null;
return this.supported[instructionSet].target[0];
}
getCompilerInstructionSetHint(compilerArch: string | boolean, exe?: string): InstructionSet {
if (compilerArch && typeof compilerArch === 'string') {
for (const [instructionSet, method] of Object.entries(this.supported) as [
InstructionSet,
InstructionSetMethod,
][]) {
for (const target of method.target) {
if (compilerArch.includes(target)) {
return instructionSet;
}
}
}
} else {
for (const [instructionSet, method] of Object.entries(this.supported) as [
InstructionSet,
InstructionSetMethod,
][]) {
for (const path of method.path) {
if (exe?.includes(path)) {
return instructionSet;
}
}
}
}
return this.defaultInstructionset;
}
}