xref: /linux/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs (revision 1ec0b899c2b776c0c2dd03044b171a52b5211570)
1*1ec0b899SSakari Ailus#!/usr/bin/perl -w
2*1ec0b899SSakari Ailus# SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
3*1ec0b899SSakari Ailus# Copyright (C) 2019--2020 Intel Corporation
4*1ec0b899SSakari Ailus
5*1ec0b899SSakari Ailususe Getopt::Long qw(:config no_ignore_case);
6*1ec0b899SSakari Ailususe File::Basename;
7*1ec0b899SSakari Ailus
8*1ec0b899SSakari Ailusmy $ccsregs = "ccs-regs.txt";
9*1ec0b899SSakari Ailusmy $header;
10*1ec0b899SSakari Ailusmy $regarray;
11*1ec0b899SSakari Ailusmy $limitc;
12*1ec0b899SSakari Ailusmy $limith;
13*1ec0b899SSakari Ailusmy $kernel;
14*1ec0b899SSakari Ailusmy $help;
15*1ec0b899SSakari Ailus
16*1ec0b899SSakari AilusGetOptions("ccsregs|c=s" => \$ccsregs,
17*1ec0b899SSakari Ailus	   "header|e=s" => \$header,
18*1ec0b899SSakari Ailus	   "regarray|r=s" => \$regarray,
19*1ec0b899SSakari Ailus	   "limitc|l=s" => \$limitc,
20*1ec0b899SSakari Ailus	   "limith|L=s" => \$limith,
21*1ec0b899SSakari Ailus	   "kernel|k" => \$kernel,
22*1ec0b899SSakari Ailus	   "help|h" => \$help) or die "can't parse options";
23*1ec0b899SSakari Ailus
24*1ec0b899SSakari Ailus$help = 1 if ! defined $header || ! defined $limitc || ! defined $limith;
25*1ec0b899SSakari Ailus
26*1ec0b899SSakari Ailusif (defined $help) {
27*1ec0b899SSakari Ailus	print <<EOH
28*1ec0b899SSakari Ailus$0 - Create CCS register definitions for C
29*1ec0b899SSakari Ailus
30*1ec0b899SSakari Ailususage: $0 -c ccs-regs.txt -e header -r regarray -l limit-c -L limit-header [-k]
31*1ec0b899SSakari Ailus
32*1ec0b899SSakari Ailus	-c ccs register file
33*1ec0b899SSakari Ailus	-e header file name
34*1ec0b899SSakari Ailus	-r register description array file name
35*1ec0b899SSakari Ailus	-l limit and capability array file name
36*1ec0b899SSakari Ailus	-L limit and capability header file name
37*1ec0b899SSakari Ailus	-k generate files for kernel space consumption
38*1ec0b899SSakari AilusEOH
39*1ec0b899SSakari Ailus	  ;
40*1ec0b899SSakari Ailus	exit 0;
41*1ec0b899SSakari Ailus}
42*1ec0b899SSakari Ailus
43*1ec0b899SSakari Ailusmy $lh_hdr = ! defined $kernel
44*1ec0b899SSakari Ailus	? '#include "ccs-os.h"' . "\n"
45*1ec0b899SSakari Ailus	: "#include <linux/bits.h>\n#include <linux/types.h>\n";
46*1ec0b899SSakari Ailusmy $uint32_t = ! defined $kernel ? 'uint32_t' : 'u32';
47*1ec0b899SSakari Ailusmy $uint16_t = ! defined $kernel ? 'uint16_t' : 'u16';
48*1ec0b899SSakari Ailus
49*1ec0b899SSakari Ailusopen(my $R, "< $ccsregs") or die "can't open $ccsregs";
50*1ec0b899SSakari Ailus
51*1ec0b899SSakari Ailusopen(my $H, "> $header") or die "can't open $header";
52*1ec0b899SSakari Ailusmy $A;
53*1ec0b899SSakari Ailusif (defined $regarray) {
54*1ec0b899SSakari Ailus	open($A, "> $regarray") or die "can't open $regarray";
55*1ec0b899SSakari Ailus}
56*1ec0b899SSakari Ailusopen(my $LC, "> $limitc") or die "can't open $limitc";
57*1ec0b899SSakari Ailusopen(my $LH, "> $limith") or die "can't open $limith";
58*1ec0b899SSakari Ailus
59*1ec0b899SSakari Ailusmy %this;
60*1ec0b899SSakari Ailus
61*1ec0b899SSakari Ailussub is_limit_reg($) {
62*1ec0b899SSakari Ailus	my $addr = hex $_[0];
63*1ec0b899SSakari Ailus
64*1ec0b899SSakari Ailus	return 0 if $addr < 0x40; # weed out status registers
65*1ec0b899SSakari Ailus	return 0 if $addr >= 0x100 && $addr < 0xfff; # weed out configuration registers
66*1ec0b899SSakari Ailus
67*1ec0b899SSakari Ailus	return 1;
68*1ec0b899SSakari Ailus}
69*1ec0b899SSakari Ailus
70*1ec0b899SSakari Ailusmy $uc_header = basename uc $header;
71*1ec0b899SSakari Ailus$uc_header =~ s/[^A-Z0-9]/_/g;
72*1ec0b899SSakari Ailus
73*1ec0b899SSakari Ailusmy $copyright = "/* Copyright (C) 2019--2020 Intel Corporation */\n";
74*1ec0b899SSakari Ailusmy $license = "SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause";
75*1ec0b899SSakari Ailus
76*1ec0b899SSakari Ailusfor my $fh ($A, $LC) {
77*1ec0b899SSakari Ailus	print $fh "// $license\n$copyright\n" if defined $fh;
78*1ec0b899SSakari Ailus}
79*1ec0b899SSakari Ailus
80*1ec0b899SSakari Ailusfor my $fh ($H, $LH) {
81*1ec0b899SSakari Ailus	print $fh "/* $license */\n$copyright\n";
82*1ec0b899SSakari Ailus}
83*1ec0b899SSakari Ailus
84*1ec0b899SSakari Ailussub bit_def($) {
85*1ec0b899SSakari Ailus	my $bit = shift @_;
86*1ec0b899SSakari Ailus
87*1ec0b899SSakari Ailus	return "BIT($bit)" if defined $kernel;
88*1ec0b899SSakari Ailus	return "(1U << $bit)" if $bit =~ /^[a-zA-Z0-9_]+$/;
89*1ec0b899SSakari Ailus	return "(1U << ($bit))";
90*1ec0b899SSakari Ailus}
91*1ec0b899SSakari Ailus
92*1ec0b899SSakari Ailusprint $H <<EOF
93*1ec0b899SSakari Ailus#ifndef __${uc_header}__
94*1ec0b899SSakari Ailus#define __${uc_header}__
95*1ec0b899SSakari Ailus
96*1ec0b899SSakari AilusEOF
97*1ec0b899SSakari Ailus  ;
98*1ec0b899SSakari Ailus
99*1ec0b899SSakari Ailusprint $H "#include <linux/bits.h>\n\n" if defined $kernel;
100*1ec0b899SSakari Ailus
101*1ec0b899SSakari Ailusprint $H <<EOF
102*1ec0b899SSakari Ailus#define CCS_FL_BASE		16
103*1ec0b899SSakari AilusEOF
104*1ec0b899SSakari Ailus  ;
105*1ec0b899SSakari Ailus
106*1ec0b899SSakari Ailusprint $H "#define CCS_FL_16BIT		" . bit_def("CCS_FL_BASE") . "\n";
107*1ec0b899SSakari Ailusprint $H "#define CCS_FL_32BIT		" . bit_def("CCS_FL_BASE + 1") . "\n";
108*1ec0b899SSakari Ailusprint $H "#define CCS_FL_FLOAT_IREAL	" . bit_def("CCS_FL_BASE + 2") . "\n";
109*1ec0b899SSakari Ailusprint $H "#define CCS_FL_IREAL		" . bit_def("CCS_FL_BASE + 3") . "\n";
110*1ec0b899SSakari Ailus
111*1ec0b899SSakari Ailusprint $H <<EOF
112*1ec0b899SSakari Ailus#define CCS_R_ADDR(r)		((r) & 0xffff)
113*1ec0b899SSakari Ailus
114*1ec0b899SSakari AilusEOF
115*1ec0b899SSakari Ailus  ;
116*1ec0b899SSakari Ailus
117*1ec0b899SSakari Ailusprint $A <<EOF
118*1ec0b899SSakari Ailus#include <stdint.h>
119*1ec0b899SSakari Ailus#include <stdio.h>
120*1ec0b899SSakari Ailus#include "ccs-extra.h"
121*1ec0b899SSakari Ailus#include "ccs-regs.h"
122*1ec0b899SSakari Ailus
123*1ec0b899SSakari AilusEOF
124*1ec0b899SSakari Ailus	if defined $A;
125*1ec0b899SSakari Ailus
126*1ec0b899SSakari Ailusmy $uc_limith = basename uc $limith;
127*1ec0b899SSakari Ailus$uc_limith =~ s/[^A-Z0-9]/_/g;
128*1ec0b899SSakari Ailus
129*1ec0b899SSakari Ailusprint $LH <<EOF
130*1ec0b899SSakari Ailus#ifndef __${uc_limith}__
131*1ec0b899SSakari Ailus#define __${uc_limith}__
132*1ec0b899SSakari Ailus
133*1ec0b899SSakari Ailus$lh_hdr
134*1ec0b899SSakari Ailusstruct ccs_limit {
135*1ec0b899SSakari Ailus	$uint32_t reg;
136*1ec0b899SSakari Ailus	$uint16_t size;
137*1ec0b899SSakari Ailus	$uint16_t flags;
138*1ec0b899SSakari Ailus	const char *name;
139*1ec0b899SSakari Ailus};
140*1ec0b899SSakari Ailus
141*1ec0b899SSakari AilusEOF
142*1ec0b899SSakari Ailus  ;
143*1ec0b899SSakari Ailusprint $LH "#define CCS_L_FL_SAME_REG	" . bit_def(0) . "\n\n";
144*1ec0b899SSakari Ailus
145*1ec0b899SSakari Ailusprint $LH <<EOF
146*1ec0b899SSakari Ailusextern const struct ccs_limit ccs_limits[];
147*1ec0b899SSakari Ailus
148*1ec0b899SSakari AilusEOF
149*1ec0b899SSakari Ailus  ;
150*1ec0b899SSakari Ailus
151*1ec0b899SSakari Ailusprint $LC <<EOF
152*1ec0b899SSakari Ailus#include "ccs-limits.h"
153*1ec0b899SSakari Ailus#include "ccs-regs.h"
154*1ec0b899SSakari Ailus
155*1ec0b899SSakari Ailusconst struct ccs_limit ccs_limits[] = {
156*1ec0b899SSakari AilusEOF
157*1ec0b899SSakari Ailus  ;
158*1ec0b899SSakari Ailus
159*1ec0b899SSakari Ailusmy $limitcount = 0;
160*1ec0b899SSakari Ailusmy $argdescs;
161*1ec0b899SSakari Ailusmy $reglist = "const struct ccs_reg_desc ccs_reg_desc[] = {\n";
162*1ec0b899SSakari Ailus
163*1ec0b899SSakari Ailussub name_split($$) {
164*1ec0b899SSakari Ailus	my ($name, $addr) = @_;
165*1ec0b899SSakari Ailus	my $args;
166*1ec0b899SSakari Ailus
167*1ec0b899SSakari Ailus	$name =~ /([^\(]+?)(\(.*)/;
168*1ec0b899SSakari Ailus	($name, $args) = ($1, $2);
169*1ec0b899SSakari Ailus	$args = [split /,\s*/, $args];
170*1ec0b899SSakari Ailus	foreach my $t (@$args) {
171*1ec0b899SSakari Ailus		$t =~ s/[\(\)]//g;
172*1ec0b899SSakari Ailus		$t =~ s/\//\\\//g;
173*1ec0b899SSakari Ailus	}
174*1ec0b899SSakari Ailus
175*1ec0b899SSakari Ailus	return ($name, $addr, $args);
176*1ec0b899SSakari Ailus}
177*1ec0b899SSakari Ailus
178*1ec0b899SSakari Ailussub tabconv($) {
179*1ec0b899SSakari Ailus	$_ = shift;
180*1ec0b899SSakari Ailus
181*1ec0b899SSakari Ailus	my @l = split "\n", $_;
182*1ec0b899SSakari Ailus
183*1ec0b899SSakari Ailus	map {
184*1ec0b899SSakari Ailus		s/ {8,8}/\t/g;
185*1ec0b899SSakari Ailus		s/\t\K +//;
186*1ec0b899SSakari Ailus	} @l;
187*1ec0b899SSakari Ailus
188*1ec0b899SSakari Ailus	return (join "\n", @l) . "\n";
189*1ec0b899SSakari Ailus}
190*1ec0b899SSakari Ailus
191*1ec0b899SSakari Ailussub elem_size(@) {
192*1ec0b899SSakari Ailus	my @flags = @_;
193*1ec0b899SSakari Ailus
194*1ec0b899SSakari Ailus	return 2 if grep /^16$/, @flags;
195*1ec0b899SSakari Ailus	return 4 if grep /^32$/, @flags;
196*1ec0b899SSakari Ailus	return 1;
197*1ec0b899SSakari Ailus}
198*1ec0b899SSakari Ailus
199*1ec0b899SSakari Ailussub arr_size($) {
200*1ec0b899SSakari Ailus	my $this = $_[0];
201*1ec0b899SSakari Ailus	my $size = $this->{elsize};
202*1ec0b899SSakari Ailus	my $h = $this->{argparams};
203*1ec0b899SSakari Ailus
204*1ec0b899SSakari Ailus	foreach my $arg (@{$this->{args}}) {
205*1ec0b899SSakari Ailus		my $apref = $h->{$arg};
206*1ec0b899SSakari Ailus
207*1ec0b899SSakari Ailus		$size *= $apref->{max} - $apref->{min} + 1;
208*1ec0b899SSakari Ailus	}
209*1ec0b899SSakari Ailus
210*1ec0b899SSakari Ailus	return $size;
211*1ec0b899SSakari Ailus}
212*1ec0b899SSakari Ailus
213*1ec0b899SSakari Ailussub print_args($$$) {
214*1ec0b899SSakari Ailus	my ($this, $postfix, $is_same_reg) = @_;
215*1ec0b899SSakari Ailus	my ($args, $argparams, $name) =
216*1ec0b899SSakari Ailus	  ($this->{args}, $this->{argparams}, $this->{name});
217*1ec0b899SSakari Ailus	my $varname = "ccs_reg_arg_" . (lc $name) . $postfix;
218*1ec0b899SSakari Ailus	my @mins;
219*1ec0b899SSakari Ailus	my @sorted_args = @{$this->{sorted_args}};
220*1ec0b899SSakari Ailus	my $lim_arg;
221*1ec0b899SSakari Ailus	my $size = arr_size($this);
222*1ec0b899SSakari Ailus
223*1ec0b899SSakari Ailus	$argdescs .= "static const struct ccs_reg_arg " . $varname . "[] = {\n";
224*1ec0b899SSakari Ailus
225*1ec0b899SSakari Ailus	foreach my $sorted_arg (@sorted_args) {
226*1ec0b899SSakari Ailus		push @mins, $argparams->{$sorted_arg}->{min};
227*1ec0b899SSakari Ailus	}
228*1ec0b899SSakari Ailus
229*1ec0b899SSakari Ailus	foreach my $sorted_arg (@sorted_args) {
230*1ec0b899SSakari Ailus		my $h = $argparams->{$sorted_arg};
231*1ec0b899SSakari Ailus
232*1ec0b899SSakari Ailus		$argdescs .= "\t{ \"$sorted_arg\", $h->{min}, $h->{max}, $h->{elsize} },\n";
233*1ec0b899SSakari Ailus
234*1ec0b899SSakari Ailus		$lim_arg .= defined $lim_arg ? ", $h->{min}" : "$h->{min}";
235*1ec0b899SSakari Ailus	}
236*1ec0b899SSakari Ailus
237*1ec0b899SSakari Ailus	$argdescs .= "};\n\n";
238*1ec0b899SSakari Ailus
239*1ec0b899SSakari Ailus	$reglist .= "\t{ CCS_R_" . (uc $name) . "(" . (join ",", (@mins)) .
240*1ec0b899SSakari Ailus	  "), $size, sizeof($varname) / sizeof(*$varname)," .
241*1ec0b899SSakari Ailus	    " \"" . (lc $name) . "\", $varname },\n";
242*1ec0b899SSakari Ailus
243*1ec0b899SSakari Ailus	print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . "($lim_arg), " .
244*1ec0b899SSakari Ailus	  $size . ", " . ($is_same_reg ? "CCS_L_FL_SAME_REG" : "0") .
245*1ec0b899SSakari Ailus	    ", \"$name" . (defined $this->{discontig} ? " $lim_arg" : "") . "\" },\n"
246*1ec0b899SSakari Ailus	      if is_limit_reg $this->{base_addr};
247*1ec0b899SSakari Ailus}
248*1ec0b899SSakari Ailus
249*1ec0b899SSakari Ailusmy $hdr_data;
250*1ec0b899SSakari Ailus
251*1ec0b899SSakari Ailuswhile (<$R>) {
252*1ec0b899SSakari Ailus	chop;
253*1ec0b899SSakari Ailus	s/^\s*//;
254*1ec0b899SSakari Ailus	next if /^[#;]/ || /^$/;
255*1ec0b899SSakari Ailus	if (s/^-\s*//) {
256*1ec0b899SSakari Ailus		if (s/^b\s*//) {
257*1ec0b899SSakari Ailus			my ($bit, $addr) = split /\t+/;
258*1ec0b899SSakari Ailus			$bit = uc $bit;
259*1ec0b899SSakari Ailus			$hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) ."_$bit", bit_def($addr) . "\n";
260*1ec0b899SSakari Ailus		} elsif (s/^f\s*//) {
261*1ec0b899SSakari Ailus			s/[,\.-]/_/g;
262*1ec0b899SSakari Ailus			my @a = split /\s+/;
263*1ec0b899SSakari Ailus			my ($msb, $lsb, $this_field) = reverse @a;
264*1ec0b899SSakari Ailus		        @a = ( { "name" => "SHIFT", "addr" => $lsb, "fmt" => "%uU", },
265*1ec0b899SSakari Ailus			       { "name" => "MASK", "addr" => (1 << ($msb + 1)) - 1 - ((1 << $lsb) - 1), "fmt" => "0x%" . join(".", ($this{"elsize"} >> 2) x 2) . "x" } );
266*1ec0b899SSakari Ailus			$this{"field"} = $this_field;
267*1ec0b899SSakari Ailus			foreach my $ar (@a) {
268*1ec0b899SSakari Ailus				#print $ar->{fmt}."\n";
269*1ec0b899SSakari Ailus				$hdr_data .= sprintf "#define %-62s " . $ar->{"fmt"} . "\n", "CCS_" . (uc $this{"name"}) . (defined $this_field ? "_" . uc $this_field : "") . "_" . $ar->{"name"}, $ar->{"addr"} . "\n";
270*1ec0b899SSakari Ailus			}
271*1ec0b899SSakari Ailus		} elsif (s/^e\s*//) {
272*1ec0b899SSakari Ailus			s/[,\.-]/_/g;
273*1ec0b899SSakari Ailus			my ($enum, $addr) = split /\s+/;
274*1ec0b899SSakari Ailus			$enum = uc $enum;
275*1ec0b899SSakari Ailus			$hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) . (defined $this{"field"} ? "_" . uc $this{"field"} : "") ."_$enum", $addr . ($addr =~ /0x/i ? "" : "U") . "\n";
276*1ec0b899SSakari Ailus		} elsif (s/^l\s*//) {
277*1ec0b899SSakari Ailus			my ($arg, $min, $max, $elsize, @discontig) = split /\s+/;
278*1ec0b899SSakari Ailus			my $size;
279*1ec0b899SSakari Ailus
280*1ec0b899SSakari Ailus			foreach my $num ($min, $max) {
281*1ec0b899SSakari Ailus				$num = hex $num if $num =~ /0x/i;
282*1ec0b899SSakari Ailus			}
283*1ec0b899SSakari Ailus
284*1ec0b899SSakari Ailus			$hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MIN_$arg"), $min . ($min =~ /0x/i ? "" : "U") . "\n";
285*1ec0b899SSakari Ailus			$hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MAX_$arg"), $max . ($max =~ /0x/i ? "" : "U") . "\n";
286*1ec0b899SSakari Ailus
287*1ec0b899SSakari Ailus			my $h = $this{argparams};
288*1ec0b899SSakari Ailus
289*1ec0b899SSakari Ailus			$h->{$arg} = { "min" => $min,
290*1ec0b899SSakari Ailus				       "max" => $max,
291*1ec0b899SSakari Ailus				       "elsize" => $elsize =~ /^0x/ ? hex $elsize : $elsize,
292*1ec0b899SSakari Ailus				       "discontig" => \@discontig };
293*1ec0b899SSakari Ailus
294*1ec0b899SSakari Ailus			$this{discontig} = $arg if @discontig;
295*1ec0b899SSakari Ailus
296*1ec0b899SSakari Ailus			next if $#{$this{args}} + 1 != scalar keys %{$this{argparams}};
297*1ec0b899SSakari Ailus
298*1ec0b899SSakari Ailus			my $reg_formula = "($this{addr}";
299*1ec0b899SSakari Ailus			my $lim_formula;
300*1ec0b899SSakari Ailus
301*1ec0b899SSakari Ailus			foreach my $arg (@{$this{args}}) {
302*1ec0b899SSakari Ailus				my $d = $h->{$arg}->{discontig};
303*1ec0b899SSakari Ailus				my $times = $h->{$arg}->{elsize} != 1 ?
304*1ec0b899SSakari Ailus				  " * " . $h->{$arg}->{elsize} : "";
305*1ec0b899SSakari Ailus
306*1ec0b899SSakari Ailus				if (@$d) {
307*1ec0b899SSakari Ailus					my ($lim, $offset) = split /,/, $d->[0];
308*1ec0b899SSakari Ailus
309*1ec0b899SSakari Ailus					$reg_formula .= " + (($arg) < $lim ? ($arg)$times : $offset + (($arg) - $lim)$times)";
310*1ec0b899SSakari Ailus				} else {
311*1ec0b899SSakari Ailus					$reg_formula .= " + ($arg)$times";
312*1ec0b899SSakari Ailus				}
313*1ec0b899SSakari Ailus
314*1ec0b899SSakari Ailus				$lim_formula .= (defined $lim_formula ? " + " : "") . "($arg)$times";
315*1ec0b899SSakari Ailus			}
316*1ec0b899SSakari Ailus
317*1ec0b899SSakari Ailus			$reg_formula .= ")\n";
318*1ec0b899SSakari Ailus			$lim_formula =~ s/^\(([a-z0-9]+)\)$/$1/i;
319*1ec0b899SSakari Ailus
320*1ec0b899SSakari Ailus			print $H tabconv sprintf("#define %-62s %s", "CCS_R_" . (uc $this{name}) .
321*1ec0b899SSakari Ailus			  $this{arglist}, $reg_formula);
322*1ec0b899SSakari Ailus
323*1ec0b899SSakari Ailus			print $H tabconv $hdr_data;
324*1ec0b899SSakari Ailus			undef $hdr_data;
325*1ec0b899SSakari Ailus
326*1ec0b899SSakari Ailus			# Sort arguments in descending order by size
327*1ec0b899SSakari Ailus			@{$this{sorted_args}} = sort {
328*1ec0b899SSakari Ailus				$h->{$a}->{elsize} <= $h->{$b}->{elsize}
329*1ec0b899SSakari Ailus			} @{$this{args}};
330*1ec0b899SSakari Ailus
331*1ec0b899SSakari Ailus			if (defined $this{discontig}) {
332*1ec0b899SSakari Ailus				my $da = $this{argparams}->{$this{discontig}};
333*1ec0b899SSakari Ailus				my ($first_discontig) = split /,/, $da->{discontig}->[0];
334*1ec0b899SSakari Ailus				my $max = $da->{max};
335*1ec0b899SSakari Ailus
336*1ec0b899SSakari Ailus				$da->{max} = $first_discontig - 1;
337*1ec0b899SSakari Ailus				print_args(\%this, "", 0);
338*1ec0b899SSakari Ailus
339*1ec0b899SSakari Ailus				$da->{min} = $da->{max} + 1;
340*1ec0b899SSakari Ailus				$da->{max} = $max;
341*1ec0b899SSakari Ailus				print_args(\%this, $first_discontig, 1);
342*1ec0b899SSakari Ailus			} else {
343*1ec0b899SSakari Ailus				print_args(\%this, "", 0);
344*1ec0b899SSakari Ailus			}
345*1ec0b899SSakari Ailus
346*1ec0b899SSakari Ailus			next unless is_limit_reg $this{base_addr};
347*1ec0b899SSakari Ailus
348*1ec0b899SSakari Ailus			print $LH tabconv sprintf "#define %-63s%s\n",
349*1ec0b899SSakari Ailus			  "CCS_L_" . (uc $this{name}) . "_OFFSET(" .
350*1ec0b899SSakari Ailus			    (join ", ", @{$this{args}}) . ")", "($lim_formula)";
351*1ec0b899SSakari Ailus		}
352*1ec0b899SSakari Ailus
353*1ec0b899SSakari Ailus		if (! @{$this{args}}) {
354*1ec0b899SSakari Ailus			print $H tabconv($hdr_data);
355*1ec0b899SSakari Ailus			undef $hdr_data;
356*1ec0b899SSakari Ailus		}
357*1ec0b899SSakari Ailus
358*1ec0b899SSakari Ailus		next;
359*1ec0b899SSakari Ailus	}
360*1ec0b899SSakari Ailus
361*1ec0b899SSakari Ailus	my ($name, $addr, @flags) = split /\t+/, $_;
362*1ec0b899SSakari Ailus	my $args = [];
363*1ec0b899SSakari Ailus
364*1ec0b899SSakari Ailus	my $sp;
365*1ec0b899SSakari Ailus
366*1ec0b899SSakari Ailus	($name, $addr, $args) = name_split($name, $addr) if /\(.*\)/;
367*1ec0b899SSakari Ailus
368*1ec0b899SSakari Ailus	$name =~ s/[,\.-]/_/g;
369*1ec0b899SSakari Ailus
370*1ec0b899SSakari Ailus	my $flagstring = "";
371*1ec0b899SSakari Ailus	my $size = elem_size(@flags);
372*1ec0b899SSakari Ailus	$flagstring .= "| CCS_FL_16BIT " if $size eq "2";
373*1ec0b899SSakari Ailus	$flagstring .= "| CCS_FL_32BIT " if $size eq "4";
374*1ec0b899SSakari Ailus	$flagstring .= "| CCS_FL_FLOAT_IREAL " if grep /^float_ireal$/, @flags;
375*1ec0b899SSakari Ailus	$flagstring .= "| CCS_FL_IREAL " if grep /^ireal$/, @flags;
376*1ec0b899SSakari Ailus	$flagstring =~ s/^\| //;
377*1ec0b899SSakari Ailus	$flagstring =~ s/ $//;
378*1ec0b899SSakari Ailus	$flagstring = "($flagstring)" if $flagstring =~ /\|/;
379*1ec0b899SSakari Ailus	my $base_addr = $addr;
380*1ec0b899SSakari Ailus	$addr = "($addr | $flagstring)" if $flagstring ne "";
381*1ec0b899SSakari Ailus
382*1ec0b899SSakari Ailus	my $arglist = @$args ? "(" . (join ", ", @$args) . ")" : "";
383*1ec0b899SSakari Ailus	$hdr_data .= sprintf "#define %-62s %s\n", "CCS_R_" . (uc $name), $addr
384*1ec0b899SSakari Ailus	  if !@$args;
385*1ec0b899SSakari Ailus
386*1ec0b899SSakari Ailus	$name =~ s/\(.*//;
387*1ec0b899SSakari Ailus
388*1ec0b899SSakari Ailus	%this = ( name => $name,
389*1ec0b899SSakari Ailus		  addr => $addr,
390*1ec0b899SSakari Ailus		  base_addr => $base_addr,
391*1ec0b899SSakari Ailus		  argparams => {},
392*1ec0b899SSakari Ailus		  args => $args,
393*1ec0b899SSakari Ailus		  arglist => $arglist,
394*1ec0b899SSakari Ailus		  elsize => $size,
395*1ec0b899SSakari Ailus		);
396*1ec0b899SSakari Ailus
397*1ec0b899SSakari Ailus	if (!@$args) {
398*1ec0b899SSakari Ailus		$reglist .= "\t{ CCS_R_" . (uc $name) . ", 1,  0, \"" . (lc $name) . "\", NULL },\n";
399*1ec0b899SSakari Ailus		print $H tabconv $hdr_data;
400*1ec0b899SSakari Ailus		undef $hdr_data;
401*1ec0b899SSakari Ailus
402*1ec0b899SSakari Ailus		print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . ", " .
403*1ec0b899SSakari Ailus		  $this{elsize} . ", 0, \"$name\" },\n"
404*1ec0b899SSakari Ailus		    if is_limit_reg $this{base_addr};
405*1ec0b899SSakari Ailus	}
406*1ec0b899SSakari Ailus
407*1ec0b899SSakari Ailus	print $LH tabconv sprintf "#define %-63s%s\n",
408*1ec0b899SSakari Ailus	  "CCS_L_" . (uc $this{name}), $limitcount++
409*1ec0b899SSakari Ailus	    if is_limit_reg $this{base_addr};
410*1ec0b899SSakari Ailus}
411*1ec0b899SSakari Ailus
412*1ec0b899SSakari Ailusif (defined $A) {
413*1ec0b899SSakari Ailus	print $A $argdescs, $reglist;
414*1ec0b899SSakari Ailus
415*1ec0b899SSakari Ailus	print $A "\t{ 0 }\n";
416*1ec0b899SSakari Ailus
417*1ec0b899SSakari Ailus	print $A "};\n";
418*1ec0b899SSakari Ailus}
419*1ec0b899SSakari Ailus
420*1ec0b899SSakari Ailusprint $H "\n#endif /* __${uc_header}__ */\n";
421*1ec0b899SSakari Ailus
422*1ec0b899SSakari Ailusprint $LH tabconv sprintf "#define %-63s%s\n", "CCS_L_LAST", $limitcount;
423*1ec0b899SSakari Ailus
424*1ec0b899SSakari Ailusprint $LH "\n#endif /* __${uc_limith}__ */\n";
425*1ec0b899SSakari Ailus
426*1ec0b899SSakari Ailusprint $LC "\t{ 0 } /* Guardian */\n";
427*1ec0b899SSakari Ailusprint $LC "};\n";
428*1ec0b899SSakari Ailus
429*1ec0b899SSakari Ailusclose($R);
430*1ec0b899SSakari Ailusclose($H);
431*1ec0b899SSakari Ailusclose($A) if defined $A;
432*1ec0b899SSakari Ailusclose($LC);
433*1ec0b899SSakari Ailusclose($LH);
434