The predicate you need to check is
if (col1 is not null and col2 is not null) then specific is not null
The predicate if A then B can be writen as not A or B
Note that the precendence is (not A) or B see the discussion here
So you get:
alter table spec add constraint my_spec
check (not (col1 is not null and col2 is not null) or specific is not null);
if col1 or col2 is null spcific is nullable
insert into spec(col1,col2,specific) values(null,null,null);
insert into spec(col1,col2,specific) values(1,null,null);
insert into spec(col1,col2,specific) values(null,1,null);
if both col1 and col2 are defined secific in NOT NULL
insert into spec(col1,col2,specific) values(1,1,1);
insert into spec(col1,col2,specific) values(1,1,null);
-- ORA-02290: check constraint (REPORTER.MY_SPEC) violated
On existing table you can add this check only if the existing data fullfill the validation, otherwise you get this exception
ORA-02293: cannot validate (OWNER.MY_SPEC) - check constraint violated
To find the rows that violated the new rule simply query
select * from spec
where NOT (not (col1 is not null and col2 is not null) or specific is not null);
You must either delete those rows or set specific to a non NULL value or set col1 or col2 to NULL.
Alternatively you may enable the constraint with NOVALIDATE option, this tolerates the existing violations, but enforce that new changes follow the constraint.
alter table spec add constraint my_spec
check (not (col1 is not null and col2 is not null) or specific is not null)
enable novalidate;